题目描述
给定方程: 8 x 4 + 7 x 3 + 2 x 2 + 3 x + 6 = = Y \ 8x^4+7x^3+2x^2+3x+6==Y 8x4+7x3+2x2+3x+6==Y, 请计算x在[0,100]范围内的解.
输入
输入数据首先是一个正整数T, 表示有T组测试数据.
接下来T行, 每行包含一个实数Y.输出
请计算并输出方程在[0,100]内的解, 结果精确到小数点后4位.
如果无解, 则请输出“No solution!”数据范围
1<=T<=100
fabs(Y) <= 1 × 1 0 10 \ 1\times10^{10} 1×1010
输入样例
2
100
-4输出样例
1.6152
No solution!
思路分析
刚刚拿到这个题的时候, 真是一点思路都没有, 但是在同学的指点下, 才解出此题.解此方程, 其实就是求
函数
f
(
x
)
=
8
x
4
+
7
x
3
+
2
x
2
+
3
x
+
6
\ f(x)=8x^4+7x^3+2x^2+3x+6
f(x)=8x4+7x3+2x2+3x+6 与直线
y
=
Y
\ y=Y
y=Y 在[0,100]内的交点, 并且
f
(
x
)
\ f(x)
f(x)在[0,100]上单调递增, 也就是说
f
(
x
)
\ f(x)
f(x)与
y
=
Y
\ y=Y
y=Y 在[0,100]最多有一个交点, 所以我们就引出了今天的主角—二分法, 相信大家二分法已经掌握的很好了 (其实看一下下面的代码, 就能对二分法略知一二了), 如果不知道可以自行百度, 网络上有不少经典的教程.
话不多数, 直接上代码.
样例代码
#include<iostream>
#include<cmath>
using namespace std;
double caculate(double x) {
return 8 * x * x * x * x + 7 * x * x * x + 2 * x * x + 3 * x + 6;
}
int main()
{
int t;
cin >> t; //有t组样例
double y;
for (int i = 0; i < t; i++)
{
cin >> y;
double left = 0, right = 100; //初始化左右边界
double x;
double ans;
if(y<6||y>8.0702e+08) //单独把不合规Y挑出来, 是因为else后的语句不会自动结束. 可以调试看一下.
cout << "No solution!" << endl;
else
{
while (left <= right) {
x = (left + right) / 2;
ans = caculate(x);
if (fabs(ans - y) < 1e-6)
{
printf("%.4f\n", x);
break;
}
else if (ans > y)
right = x;
else if (ans < y)
left = x;
}
}
}
}