P1024 一元三次方程求解
来源:洛谷 ★ 800
本题活力0.26按难度、完成结果与训练证据估算
算法如山行则将至
题目描述
求解三次方程的三个实根,并按从小到大输出,精确到小数点后两位。
思考与重做
王梓豪的同题记录 · 1 条
- 王梓豪 · 2026-08-11本次记录最后更新 2026.8.12
完成结果:未记录
二分递归有时可以用while循环来代替,要注意浮点数误差,大概用1e-8左右,注意相乘还有可能出现溢出的情况
队友同题 · 1 人1 条记录
完成结果:未记录已结束复习安排
浮点数运算需要加强,遇到了很多浮点数的问题
代码
#include <bits/stdc++.h>
using namespace std;
double a, b, c, d;
double value(double x)
{
return a * x * x * x + b * x * x + c * x + d;
}
void solve(double i, double i1)
{
if (value(i) == 0)
{
if (fabs(i)< 0.0005)
i = 0;//防止输出-0,虽然好像这里没有输出-0的风险
cout << fixed << setprecision(2) << i << ' ';
return;
}
double l = i, r = i1;
double lv = value(l);
while (r - l > 1e-7)//循环代替递归
{
double x = (l + r) / 2.0;
double temp = value(x);
if (temp == 0)
{
if (fabs(x) < 0.0005)
x = 0;
cout << fixed << setprecision(2) << x << ' ';
return;
}
if ((lv < 0 && temp > 0) || (lv > 0 && temp < 0))
{
r = x;
}
else
{
l = x;
lv = temp;
}
}
double x = (l + r) / 2.0;
if (fabs(x) < 0.0005)
x = 0;
cout << fixed << setprecision(2) << x << ' ';
}
int main()
{
cin >> a >> b >> c >> d;
double v[201];
for (int i = 0; i < 201; i++)
{
double x = i - 100.0;
v[i] = value(x);
}
vector<double> q;
for (int i = 0; i < 200; i++)
{
if (v[i] == 0)
{
q.push_back(i - 100.0);
}
else if ((v[i] < 0 && v[i + 1] > 0) ||
(v[i] > 0 && v[i + 1] < 0))
{
q.push_back(i - 100.0);
}
}
if (v[200] == 0)
{
q.push_back(100.0);
}
for (int i = 0; i < q.size(); i++)
{
solve(q[i], q[i] + 1.0);
}
return 0;
}