题目链接:
方法一、二分
因为区间很大,所以可以二分。
三个答案都在 [ − 100 , 100 ] [-100,100] [−100,100]范围内,两个根的差的绝对值 ⩾ 1 \geqslant1 ⩾1,保证了每一个大小为 1 1 1的区间里至多有 1 1 1个解,也就是说当区间的两个端点的函数值异号时区间内一定有一个解,同号时一定没有解。那么我们可以枚举互相不重叠的每一个长度为 1 1 1的区间,在区间内进行二分查找。
#include <bits/stdc++.h>using namespace std;
double a, b, c, d, l, r, mid;
double f(double x) {return a * x * x * x + b * x * x + c * x + d;
}
int main()
{int cnt = 0;cin >> a >> b >> c >> d;for (int i = -100; i <= 99; i++) {l = i, r = i + 1;if (!f(l)) { printf("%.2f ", l);cnt ++;//解的数量增加一个}//判断左端点,是零点直接输出//不能判断右端点,会重复if (f(l) * f(r) < 0) {while (r - l > 1e-4) { //控制精度mid = (l + r) / 2;if (f(l) * f(mid) <= 0) r = mid; else l = mid;}printf("%.2f ", l);cnt ++;}if (cnt == 3) break; //出现3个根直接break掉}return 0;
}
方法二、暴力枚举
#include <bits/stdc++.h>using namespace std;int main()
{double a, b, c, d;cin >> a >> b >> c >> d;for (double i = -100; i <= 100; i += 0.001) // 由于题目要求精确到两位小数,于是逐步递增0.001{double j = i + 0.001;double y1 = a * i * i * i + b * i * i + c * i + d;double y2 = a * j * j * j + b * j * j + c * j + d;if (y1 >= 0 && y2 <= 0 || y1 <= 0 && y2 >= 0){double x = (i + j) / 2;printf("%.2f ",x);}}
}