《训练指南》——7.17
Q:解方程pe^(-x) + qsin(x) + rcos(x) + stan(x)+tx^2 + u = 0,其中0≤x≤1.(Problem source : uva 10341)
输入格式:输入包含不超过2100组数据,包含6个整数p、q、r、s、t、u(0≤p,r≤20,-20≤q、s、t≤0)。
输出格式:对于每组数据,输出所有解,按照从小到大顺序排列,每个解均保留小数点后4位。如果无解,输出No solution。
分析:对于这种打上眼方程非常复杂的,我们肯定无法利用求根公式去求解,因此这里我们要利用数值方法中最常见的一个方法——二分法。
另外其实在这里通过6个整型参数的取值,我们能够直接判断这个函数f(x)是单调递减的,也就是说题设中所谓的“从小到大输出多组解”仅仅是起到迷惑作用的。
在二分法的设计中,我们需要解决的一个很重要的问题是何时结束二分过程,这里既可以通过设置区间的长度(1/100000),也可以通过设置二分的次数(100)。下面给出后面这种做法的代码实现:
#include<cstdio> #include<cmath> using namespace std; double p , q , r , s , t , u; double Fun(double x) { double num; num = p*exp(-x) + q*sin(x) + r*cos(x) + s*tan(x) + t*x*x + u;//e^x用数学库中的函数 return num; } int main() { while(scanf("%lf%lf%lf%lf%lf%lf",&p , &q , &r , &s , &t , &u) != EOF) { if(Fun(1.0)*Fun(0.0) > 0) printf("No solution\n"); else { double r , l , m; r = 1 , l = 0; for(int i = 1;i <= 100;i++) { m = (r + l)/2.0; if(Fun(m) >= 0) l = m; else r = m; } printf("%.4lf\n",m); } } }