解法一:使用暴力枚举
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;
int main(){
double a, b, c, d;
cin >> a >> b >> c >> d;
for(double i = -100.0; i <= 100.0; i += 0.01) {
double value = a * pow(i, 3) + b * pow(i, 2) + c * i + d;
if(fabs(value) < 0.001) {
cout<<fixed << setprecision(2) << i <<" ";
}
}
return 0;
}
这个方法就是把所有解的可能解一个一个的列举对比,符合条件就输出。这里一共有20000个,也不算多。是一个比较省时间的方法。但是缺点就是不能应用在数量大的题目上。
方法二:通过进行整数的列举去寻找,同时通过牛顿法迭代进行求解根
科普牛顿法:
基本原理
假设我们要求解方程 f(x)=0 的根,牛顿迭代法的基本思想是从一个初始猜测值 x0 开始,通过迭代公式逐步逼近真实的根。迭代公式为:
其中,f′(xn) 是函数 f(x) 在 xn 处的导数。
迭代过程
- 选择一个初始猜测值 x0。
- 计算 f(x0) 和 f′(x0)。
- 使用迭代公式计算 x1。
- 重复步骤 2 和 3,直到
(即相邻两次迭代的差的绝对值)小于某个预定的容差 ϵ,或者达到预定的迭代次数。
#include<iostream>
#include<cmath>
#include<iomanip>//这个头文件是用来控制输出的精度0.01
using namespace std;
void root(const float a,const float b,const float c,const float d,float x);
int main(){
float a,b,c,d;
cin>>a>>b>>c>>d;
for(int i=-100;i<=100;i++){
if((a*pow(i,3)+b*pow(i,2)+c*i+d)==0.00)
{
cout<<fixed << setprecision(2)<<i*1.00<<" ";
}else if((a*pow(i,3)+b*pow(i,2)+c*i+d)>0&&(a*pow(i+1,3)+b*pow(i+1,2)+c*(i+1)+d)<0)
{
root( a,b,c, d, i);
}else if((a*pow(i,3)+b*pow(i,2)+c*i+d)<0&&(a*pow(i+1,3)+b*pow(i+1,2)+c*(i+1)+d)>0)
{
root( a,b,c, d, i);
}
}
return 0;
}
void root(const float a,const float b,const float c,const float d,float x){
float num=x,x0,f,f1;
do
{
x0=x;
f=((a*x0+b)*x0+c)*x0+d;
f1=(3*a*x0+2*b)*x0+c;
x=x0-f/f1;
if(fabs(f1)<1e-6)//这个是导数接近于零时退出,因为分母不能为0,这时候不能求出x就退出
{
break;
}
}while(fabs(x-x0)>1e-6);//精度自己调整,仅做参考
cout<<fixed << setprecision(2)<<x<<" ";//控制输出精度为两个小数(0.01)
}