二分法解方程近似解

二分法解方程近似解

基礎知識:

如果要求已知函數 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;

只要判定中值符號即可

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

    }

}

 


發佈了39 篇原創文章 · 獲贊 14 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章