描述
题解
一开始这个题想多了,想着可能需要求导求极点拐点之类的东西,后来直接暴力过了一发(代码 One),然而这个方法不是特别满意,于是仔细分析了发现,题目给了很强的两个条件,保证存在三个不同的实根,且根于根直接差大于等于 1,那么我们知道一元三次方程组的解至多只有三个,所以一定是不存在峰值刚好为 0 的情况,这样直接枚举所有长度为 1 的区间,进行判断是否存在根,存在时二分即可(代码 Two)。
代码
One:
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN = 100;
const double ESP = 1e-5;
double a, b, c, d;
double calculate(double x)
{
return a * x * x * x + b * x * x + c * x + d;
}
int main(int argc, const char * argv[])
{
cin >> a >> b >> c >> d;
int cnt = 3;
for (double i = -MAXN; i <= MAXN && cnt; i += 0.01)
{
if (fabs(calculate(i)) < ESP)
{
if (cnt == 1)
{
printf("%.2f\n", i);
}
else
{
printf("%.2f ", i);
}
cnt--;
}
}
return 0;
}
Two:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double ESP = 1e-5;
const int MAXN = 100;
double a, b, c, d;
double cal(double x)
{
return a * x * x * x + b * x * x + c * x + d;
}
int main()
{
cin >> a >> b >> c >> d;
int cnt = 3;
for (int i = -MAXN; i <= MAXN; i++)
{
double l = i, r = l + 1;
if (cal(l) == 0)
{
if (cnt > 1)
{
printf("%.2f ", l);
}
else if (cnt == 1)
{
printf("%.2f\n", l);
}
else
{
break;
}
cnt--;
}
else
{
if (cal(l) * cal(r) < 0)
{
while (r - l > ESP)
{
double m = (l + r) / 2;
if (cal(l) * cal(m) <= 0)
{
r = m;
}
else
{
l = m;
}
}
if (cnt > 1)
{
printf("%.2f ", l);
}
else if (cnt == 1)
{
printf("%.2f\n", l);
}
else
{
break;
}
cnt--;
}
}
}
return 0;
}