如果要求已知函数 f(x) = 0 的根 (x 的解),那么先要找出一个区间 [a, b],使得f(a)与f(b)异号。
根据介值定理,这个区间内一定包含着方程式的根。
求该区间的中点m=(a+b)/2,并找出 f(m) 的值。
若 f(m) 与 f(a) 正负号相同,则取 [m, b] 为新的区间, 否则取 [a, m]。
重复第3步和第4步,直到得到理想的精确度为止。
Solve the equation:
p ∗ e −x + q ∗ sin(x) + r ∗ cos(x) + s ∗ tan(x) + t ∗ x 2 + u = 0 where 0 ≤ x ≤ 1.
Input
Input consists of multiple test cases and terminated by an EOF. Each test case consists of 6 integers in a single line: p, q, r, s, t and u (where 0 ≤ p, r ≤ 20 and −20 ≤ q, s, t ≤ 0). There will be maximum 2100 lines in the input file.
Output
For each set of input, there should be a line containing the value of x, correct up to 4 decimal places, or the string ‘No solution’, whichever is applicable.
Sample Input
0 0 0 0 -2 1
1 0 0 0 -1 2
1 -1 1 -1 -1 1
Sample Output
0.7071
No solution
0.7554
题意:
用程序解出方程的根。其中,输入是p q r s t u 6个量。
大概思路:
我想到的是迭代法和二分法来求近似解。因为,题目一开始就给出了x的取值范围,这就是和介值定理有相关的地方。
AC代码:
#include
#include
#include
using namespace std;
int p, q, r, s, t, u;/*用全局变量定义输入变量,可免去重复定义函数的麻烦*/
double ha(double x);
double haha(double m, double n);
int main()
{
//freopen("a.txt", "r", stdin);
while(scanf("%d%d%d%d%d%d", &p, &q, &r, &s, &t, &u) != EOF)
{
double a, b, x, huh1, huh2;
a = 0;
huh1 = ha(a);
b = 1;
huh2 = ha(b);
if(abs(huh1) <= 0.000001)
printf("0.0000\n");
else if(abs(huh2) <= 0.000001)
printf("1.0000\n");
else if(huh1*huh2 > 0)
printf("No solution\n");
else
{
x = haha(a, b);
printf("%.4f\n", x);
}
}
return 0;
}
double ha(double x)
{
double y;
y = p*exp(-x) + q*sin(x) + r*cos(x) + s*tan(x) + t*pow(x,2) + u;/*定义函数*/
return y;
}
double haha(double m, double n)
{
double x, y, y1, y2, a, b;
a = m;
b = n;
while(1)
{
x = (a+b)/2;
y = ha(x);
if(fabs(y) < 0.000001)
return x;
y1 = ha(a);
y2 = ha(b);
if(y*y1 < 0) b = x;//若最左端点的因变量和中值异号则使b=x
if(y*y2 < 0) a = x;//同理使a=x
/********************************************************************
其实上面的改变范围有些麻烦可以用下面的方法:
if(y < 0) b = x; else a = x;
只要判定中值符号即可
********************************************************************/
}
}