求方程的根的方法

例题:求方程:8x^4 + 7x^3 + 2x^2 + 3x + 6 == Y在[0,100]之间的解
Input
输入的第一行包含一个整数T(1 <= T <=100),表示测试用例的数目。接下来T个数字,每一行都有一个实数Y(abs(Y)<=1e6);
Output
对于每个测试用例,如果有解,你应该输出一个实数(精确到小数点后4位,四舍五入),如果在0到100之间无解,就输出“No solution!”。
本题其实就是让求出该方程的近似解,而求方程的近似解有很多方法,其中包括二分法和迭代法:
1、二分法:
二分法的思想就是在区间[a,b]上,取其中点,通过判断f((a+b)/2)的大小来判断根的范围,从而减小一般的区间,这种方法的时间复杂度为:O(logn)。
代码如下:

#include
#include
#include
using namespace std;
const double ee = 1e-4;
int er_fen(double n,double y)
{
double ans = 8 * pow(n, 4) + 7 * pow(n, 3) + 2 * pow(n, 2) + 3 * n + 6 - y;
if (ans >= 0) return 0;
return 1;
}
int main()
{
int T;
double y;
cin >> T;
while (T--)
{
cin >> y;
double x1 = 0, x2 = 100, s=0, x0;
while (x2 - x1 > ee)
{
x0 = (x1 + x2) / 2;
if (er_fen(x0, y))
x1 = x0;
else
x2 = x0;
s = x0;
}
printf("%.4lf\n", s);
}
return 0;
}

2、迭代法(牛顿切线法):
迭代法就是利用函数的切线来做题,开始时在函数值与二次导数所对应的函数正负一样的一端做切线,比如在x0处做切线,则切线方程为:y-f(x0)=f’(x0)(x-x0),令y=0得:x1=x0-f(x0)/f’(x0),这里的x1就是这条切线与X轴的交点的横坐标,它比x0更接近方程的根,再在点(x1,f(x1))处做切线,可得近似值x2,如此继续,就得到了一个迭代关系式:xn+1=xn-f(xn)/f’(xn),这样就可以找到根的近似值。
代码如下:

#include
#include
#include
using namespace std;
const double ee = 1e-4;``
double die_dai(double x1,double y)
{
return x1 - (8 * pow(x1, 4) + 7 * pow(x1, 3) + 2 * pow(x1, 2) + 3 * x1 + 6 - y) / (32 * pow(x1, 3) + 21 * pow(x1, 2) + 4 * x1 + 3);
}
int main()
{
int T;
double y;
cin >> T;
while (T--)
{
cin >> y;
double x1, x2;
if ((6 - y) * 4 > 0)
{
x1 = 0;
}
else
x1 = 100;
x2 = die_dai(x1, y);
while (abs(x2 - x1) > ee)
{
x1 = x2;
x2 = die_dai(x1,y);
}
printf("%.4lf\n", x1);
}
return 0;
}

你可能感兴趣的:(求方程的根的方法)