洛谷 P1024 一元三次方程求解
题目描述
有形如: ax3 + bx2 + cx1 + dx0 = 0 这样的一个一元三次方程。给出该方程中各项的系数( a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在 -100 至 100 之间),且根与根之差的绝对值 ≥1 。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 22 位。
提示:记方程 f(x)=0 ,若存在 2 个数 x1 和 x2 ,且 x1<x2 , f(x1) × f(x2) < 0 ,则在 (x1,x2) 之间一定有一个根。
输入输出格式
输入格式:
一行, 4 个实数 A,B,C,D 。
输出格式:
一行, 3 个实根,并精确到小数点后 2 位。
输入输出样例
输入样例#1: 复制
1 -5 -4 20
输出样例#1: 复制
View Code
-2.00 2.00 5.00
思路:二分
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; double a, b, c, d; double f(double x) { return a*x*x*x + b*x*x + c*x + d; } double find1(double l, double r) { while(r-l >= 0.000000001) { double mid = (l+r) / 2; double aa = f(mid); if(aa > 0) l = mid+0.000000001; else if(aa < 0) r = mid-0.000000001; else if(aa == 0.0) return mid; } return l; } double find2(double l, double r) { while(r-l >= 0.000000001) { double mid = (l+r) / 2; double aa = f(mid); if(aa < 0) l=mid+0.000000001; else if(aa > 0) r = mid-0.000000001; else if(aa == 0.0) return mid; } return l; } int main() { scanf("%lf%lf%lf%lf",&a,&b,&c,&d); for(int i = -100; i < 100; i++) { double l = f(i); double r = f(i+1); if(l == 0.0) printf("%.2lf ", double(i)); else if(l>0 && r<0) printf("%.2lf ", find1(i, i+1)); else if(l<0 && r>0) printf("%.2lf ", find2(i, i+1)); } if(f(100.0) == 0.0) printf("100.00\n"); return 0; }