题目链接

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主要是给的条件不苛刻。