题目链接
https://www.dotcpp.com/oj/problem1601.html
解题思路
代码1:
因为精度只是小数点后两位,且根的范围在-100~100;重要条件:有三个不同的根。
因此,我们可以从-100到100循环+0.01,枚举所有根的可能,判断是否满足方程。
时间复杂度O(200*100),完全可以接受。
代码2:
重要条件:任意两根差的绝对值大于等于1。
我们可以让循环找根的循环控制变量每次+1。
如果枚举的左右端点对应的函数值的乘积小于0,说明存在根在此区间内,进行二分找根;
如果枚举的左右端点对应的函数值的乘积大于0,说明不存在根;
如果枚举的左端点对应的函数值等于0,说明此点为根。
代码1
#include<bits/stdc++.h> #define esp 1e-7 using namespace std; double a,b,c,d; int cnt; double fun(double x){ return a*x*x*x+b*x*x+c*x+d; } int main(){ cin>>a>>b>>c>>d; for(double i=-100;i<=100;i+=0.01){ if(fabs(fun(i))<esp){//浮点数判断等于0,尽量使用esp判断 cnt++; if(cnt==3) printf("%.2lf",i); else printf("%.2lf ",i); } } return 0; }
代码2
#include<bits/stdc++.h> using namespace std; const double esp=1e-7; double a,b,c,d; double fun(double x){ return a*x*x*x+b*x*x+c*x+d; } //二分是重点! double erfen(double l,double r){ double mid=(l+r)/2; while(fabs(fun(mid))>esp){//找到的这个点不满足方程 mid=(l+r)/2; if(fun(l)*fun(mid)>=0) l=mid;//说明根在右半段区间内 else r=mid;//说明根在左半段区间内 } return mid; } int main(){ int cnt=3;//找三个根 cin>>a>>b>>c>>d; for(int i=-100;i<=100;i++){ double l=i,r=l+1; if(fun(l)==0){//不知道为什么这里用esp无法AC if(cnt>1) printf("%.2lf ",l); else if(cnt==1) printf("%.2lf",l); else break; cnt--; } else{ if(fun(l)*fun(r)<0){ if(cnt>1) printf("%.2lf ",erfen(i,i+1)); else if(cnt==1) printf("%.2lf",erfen(i,i+1)); else break; cnt--; } } } }
总结
自己做的时候没大动脑子,直接不会。
直接暴力都ok,我太菜了。
暴力ok主要是给的条件不苛刻。