本文章意在记录自己做题时候遇到的问题或者疑惑 希望自己能记住 或者后日解决疑惑
方法一:二分法
#include<bits/stdc++.h>
using namespace std;
//double a,b,c,d;
double san(double a,double b,double c,double d,double x)//注意返回的类型!一开始我顺手写成 int 导致错的很惨
{
return a*pow(x,3)+b*pow(x,2)+c*x+d;
//这里好像可以不用传abcd的形参
//只要和main函数中同名就好了
//但是如果 这里 不传形参 要在前面定义 double a,b,c,d;
}
int main()
{
double a,b,c,d,x,m,l,r,x1,x2;
int s=0;//因为说只有三个解 所以数到三个的时候就直接break
cin>>a>>b>>c>>d;
for(int i=-100;i<100;i++)
//因为说两个根的差的绝对值大于等于1
//每一个大小为1的区间内 至多只有一个解
//所以i++和r=i+1 其实是在搜索每一个长度为1的区间
{
l=i;
r=i+1;
x1=san(a,b,c,d,l);
x2=san(a,b,c,d,r);
if(!x1)//如果这个点刚好是零点就直接输出
{
printf("%.2lf ",l);
s++;
}
if(x1*x2<0)//这里是如果x2和x1异号 就开始缩小区间范围
{
while(r-l>=0.001)//因为说实根要精确到小数点后两位
{ //让解的范围 精确到后三位小数 可能 更精确一点吧
m=(r+l)/2;
if(san(a,b,c,d,m)*san(a,b,c,d,r)<=0)//不要漏掉等号
{
l=m; //二分法求解零点
}
else
{
r=m;
}
}
printf("%.2lf ",r);//其实输出r l都可以
s++;
}
if(s==3)
{
break;//如果已经找到三个解了 那就退出 节省时间
}
}
return 0;
}
方法二:暴力枚举