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

京公网安备 11010502036488号