二分法解方程近似解

二分法解方程近似解

基础知识:

如果要求已知函数 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 <iostream>

#include <cstdio>

#include <cmath>

 

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;

只要判定中值符号即可

********************************************************************/

    }

}

 


猜你喜欢

转载自blog.csdn.net/songziqi98/article/details/79154490
今日推荐