这道题WA了将近两天!!!!!我最近一写题就WA,一WA就一天!!!!简直有毒。
题目里说了根的范围是 (−100,100) ,而且根与根之差的绝对值>=1,那么思想就是把 (−100,100) 分成 [−100,−99] 、 [−99,−98] ……这样一个一个的区间,看看区间端点a、b,f(a) * f(b)是否<0,是的话就对这个区间二分,找出答案。
这道题不能直接二分,因为它不是一个单调区间。超超超超超级棒的ilern跟我说如果是单调区间就可以直接二分,如果不是的话就把它划分成几个单调区间来二分。
知道了思想之后还是WA,原因是double
用的不熟练。
double
类型,输入用%lf
, 输出是%.2lf
, 2是要求保留2位小数。
float用%f
输入,%.2f
输出。
printf(“%03d”, 25)
的结果是025
,%3d
的结果是25
。就可以控制输出的格式。
需要注意的是用double需要注意精度,比较和常数的大小啊啥的都要允许有误差。可以定义 const double EPS = 1e-7;
#include <cstdio>
#include <cmath>
const double EPS = 1e-7;
double a, b, c, d, x1, x2, x3, l[4], r[4];
double f(double x)
{
return a * x * x * x + b * x * x + c * x + d;
}
double find(double l, double r)
{
//printf("find(%lf, %lf)\n", l, r);
if (fabs(l - r) <= EPS || fabs(f((l + r) / 2)) <= EPS)
{
return (l + r) / 2;
}
else
{
if (f(l) * f((l + r) / 2) <= EPS)
{
return find(l, (l + r) / 2);
}
else
{
return find((l + r) / 2, r);
}
}
}
bool have(double a, double b)
{
//double fa = f(a), fb = f(b);
//printf("f(a = %.3lf) = %.3lf, f(b = %.3lf) = %.3lf\n", a, fa, b, fb);
if (f(a) * f(b) <= EPS)
{
return true;
}
else
{
return false;
}
}
int main()
{
scanf("%lf %lf %lf %lf", &a, &b, &c, &d);
int cnt = 0;
for (int i = -100; i < 100; i++)
{
double j = i + 1 - EPS;
if (have(i, j) == true)
{
l[cnt] = i;
r[cnt] = j;
cnt++;
}
}
x1 = find(l[0], r[0]);
x2 = find(l[1], r[1]);
x3 = find(l[2], r[2]);
printf("%.2lf %.2lf %.2lf\n", x1, x2, x3);
return 0;
}
第一种。。。。。。我自己的bug找不出来,然后很表脸的去找了【dalao】debug,然后输出中间变量的调试方法get√【最近用gdb就只会设断点,跑跑跑,都不会输出中间变量了= =】
有的时候要加fabs【实数去绝对值,整数是abs】【例如f(d) == 0
就要改成fabs(f(d)) <= EPS
】,但是有的时候不用加。
#include <cstdio>
#include <cmath>
const double EPS = 1e-7;
double a, b, c, d, x1, x2, x3;
double f(double x)
{
return a * x * x * x + b * x * x + c * x + d;
}
bool have(double a, double b)
{
// double fa = f(a), fb = f(b);
// printf("f(a = %.3lf) = %.3lf, f(b = %.3lf) = %.3lf\n", a, fa, b, fb);
if (f(a) * f(b) <= EPS)
{
return true;
}
else
{
return false;
}
}
void find(double l, double r)
{
//printf("find(%lf, %lf)\n", l, r);
double d = (l + r) / 2;
if ((r - l) <= EPS || fabs(f(d)) <= EPS)
{
printf("%.2lf ", d);
return;
}
else
{
if (f(l) * f(d) <= EPS)
{
find(l, d);
}
else
{
find(d, r);
}
}
}
int main()
{
scanf("%lf %lf %lf %lf", &a, &b, &c, &d);
for (int i = -100; i < 100; i++)
{
if (have(i, i + 1 - EPS) == true)
{
find(i, i + 1 - EPS);
//printf("%d\n", i);
}
else continue;
}
return 0;
}
第二种。。。。。。【然而并没有太大的差别(:з」∠)】
这个WA了很久的原因是主函数里i在循环的时候如果解是整数,就当i= i和i+ 1的时候都符合have,它都会输出。然后把边界定成(i, i + 1 - EPS)就行了。
【我还是太差了,这道并不算很难的题写了好久,有的bug自己还看不出来qnq】