1. 程式人生 > 其它 >P1024 [NOIP2001 提高組] 一元三次方程求解

P1024 [NOIP2001 提高組] 一元三次方程求解

題目連結

https://www.luogu.com.cn/problem/P1024

題目思路

二分 :根據題意,兩根乘積 < 0,兩根之間必有根,並且兩根之差 >= 1,所以以1為大區間,若兩根乘積為負則二分尋找

暴力 :因為保留兩位小數,則每次縮小區間0.01,直接尋找乘積為0的兩根,其平均數的近似值即為根

題目程式碼

二分

#include <iostream>
#include <algorithm>

using namespace std;
double a, b, c, d;

double f(double x)
{
    return a * x * x * x + b * x * x + c * x + d;
}

int main()
{
    double x1, x2;
    double l, r;
    scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
    for(double i = -100; i < 100; i ++)
    {
        l = i, r = i + 1;
        x1 = f(l), x2 = f(2);
        if(x1 == 0) printf("%.2f ", l);
        if(x1 * x2 < 0)
        {
            while(r - l >= 1e-3)
            {
                double mid = (l + r) / 2;
                if(f(mid) * f(r) <= 0) l = mid;
                else r = mid;
            }
            printf("%.2f ", r);
        }
    }
    return 0;
}

暴力

#include <iostream>
#include <algorithm>

using namespace std;


int main()
{
    double a, b, c, d;
    scanf("%lf%lf%lf%lf", &a, &b, &c, &d);
    for(double i = -100; i <= 100; i += 0.001)
    {
        double j = i + 0.001;
        double ans1 = a * i * i * i + b * i * i + c * i + d;
        double ans2 = a * j * j * j + b * j * j + c * j + d;
        if(ans1 >= 0 && ans2 <= 0 || ans1 <= 0 && ans2 >= 0)
        {
            double x = (i + j) / 2;
            printf("%.2f ", x);
        }
    }
    return 0;
}