算法竞赛入门经典:第八章 高效算法设计 8.12非线性方程求根

来源:互联网 发布:幼儿园网站整站源码 编辑:程序博客网 时间:2024/05/16 10:06
/*非线性方程求根:一次向银行借a元钱,分b月还清。如果需要每月还c元,月利率是多少(按复利率计算)?例如借2000元,分4个月每月还510,则月利率为0.797%。答案应不超过100%。思路:设月利率为x,则第一个月还钱后还需还a(1+x)-c,重复b个月后可以得到方程输入:2000 4 510输出:0.797%*//*关键:1 使用猜数字方法,对于百分数,我们把%100提取出来,分子为[0,100]之间的数字,本质上时二分法2 while(high - low > 1e-5)//利用high-low与精度值的比较来确定循环退出条件3 本题上下限的更新是根据f(x)的单调性确定,本题单调增,因此,sum>0表明mid选大了,  if(sum > 0)//说明mid选大了,在小区间{high = mid;}4 更新复利的计算表达式为a(1+x)-c,即sum += sum*mid/100.0 - c;//更新剩余所需要还的钱,是加上本月的利息sum*mid/100.0,再减去本月还的钱*/#include <stdio.h>//采用[0,100]区间缩小的方法void nonlinearEquation(float a,int b,float c){float low = 0,high = 100;while(high - low > 1e-5)//利用high-low与精度值的比较来确定循环退出条件{float mid = low + (high - low)/2;float sum = a;for(int i = 0 ; i < b ; i++){sum += sum*mid/100.0 - c;//更新剩余所需要还的钱,是加上本月的利息sum*mid/100.0,再减去本月还的钱}if(sum > 0)//说明mid选大了,在小区间{high = mid;}else{low = mid;}}printf("%.3lf%%\n",low);//要打印出“%”必须连续写两个%%//printf("%%\n");//printf("%\n");}void process(){float a,c;int b;while(EOF != scanf("%f %d %f",&a,&b,&c)){nonlinearEquation(a,b,c);}}int main(int argc,char* argv[]){process();getchar();return 0;}

0 0
原创粉丝点击