水题一道 枚举+二分方法
因为题目已经说了根与根之间的绝对值相差大于1,因此可以枚举每一个长度为一的小区间,在这个小区间二分即可
有两点要注意的:
1.精度的控制,一开始WA是因为精度没设置好,想着直接用int time = 50;while(time--)循环 但是这样wa了 改成while(right-left)之后就过了
2.区间要设置成左闭右开或者右闭左开的(如果是左闭右开最后再判断一下100,右闭左开则一开始判断一下-100),这样做的目的是为了防止重复枚举区间的边际值。
其他好像也没有什么坑点了 上代码:
#include <iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
int cnt = 0;
double ans[3];
double a,b,c,d;
double cal(double x)
{
return a*x*x*x +b*x*x +c*x +d;
}
void Find(double left,double right)
{
double temp1 = cal(left);
double temp2 = cal(right);
double mid = (left+right)/2;
int time = 100;
while(right-left>=0.001)
{
if(cal(mid) == 0)
{
ans[cnt++] = mid;
return;
}
if(cal(left) *cal(mid) >0)
left = mid;
else right = mid;
mid = (left+right)/2;
}
ans[cnt++] = mid;
}
void Solve()
{
for(int i= -100,j = -99;i<=99;i++,j++)
{
if(cnt>3)return;//已经找到3个答案了
double temp1 = cal(i),temp2 = cal(j);
if(temp1 == 0)
{
ans[cnt++] = i;//左闭右开的区间
cout<<i<<" "<<j<<endl;
}
else if(temp1*temp2 < 0)
{
cout<<i<<" " <<j<<endl;
Find(i,j);
}
}
if(cal(100) == 0 && cnt<3)ans[cnt++] = 100;
}
int main()
{
while(cin>>a>>b>>c>>d)
{
cnt = 0;
Solve();
cout<<fixed<<setprecision(2)<<ans[0]<<" "<<ans[1]<<" "<<ans[2];//<<endl;
}
}