您的位置:首页 > 其它

GDUFS1151 General Problem 解一元三次方程

2011-03-27 19:11 246 查看
Problem Address:http://cstfs.gdufs.edu.cn:8080/PKU/showproblem?problem_id=1151

一道解一元三次方程的题目。训练时没有做出来。

解题代码过来后看了一下。着实是不知道里面是怎么计算的,但是结果又是对的。

就着那个代码提交了两次还是WA。

在群上吼了一下没人理= =

整个下午也是找了好久的解一元三次方程的方法,不过都不适用于计算机。

于是决定自己写一个。

然后DEBUG了之后居然一次AC。那个兴奋啊。

主要思路:

这道题比较特殊,那就是存在三个不同的解,且每个解之间的差距不小于1.000。

求出导函数。求出导函数的两个解即为中间一个解的范围。然后迭代出中间一个解。

之后向范围的两边分别每次递增1.000。求出左右两边两个解各自的范围。然后再各自迭代求解。

因为这道题有1、必定存在三个不同的解 2、每个解差距大于1.000, 才可以这样做。

如果没有差距这个限制可能就得重新考虑一下。如果存在相同的解那我就……

#include<iostream>
#include<cmath>
using namespace std;
double a,b,c,d;
double solve(double s, double e)
{
double t;
double temp;
double left = a*s*s*s+b*s*s+c*s+d, right = a*e*e*e+b*e*e+c*e+d;
if (left*10000.0<5 && left*10000.0>-5) return left;
if (right*10000.0<5 && right*10000.0>-5) return right;
while((e-s)*100000.0<-1 || (e-s)*100000.0>1)
{
t = (s+e)/2;
temp = a*t*t*t+b*t*t+c*t+d;
if (temp*left>0)
{
left = temp;
s = t;
}
else
{
right = temp;
e = t;
}
}
if(t*10000.0<5 && t*10000.0>-5)
t=0.000;
return t;
}
double getpos(double s, double dx)
{
double t = s+dx;
double start = a*s*s*s+b*s*s+c*s+d, end = a*t*t*t+b*t*t+c*t+d;
while(start*end>0)
{
start = end;
t += dx;
end = a*t*t*t+b*t*t+c*t+d;
}
if (dx<0) return solve(t, t-dx);
else return solve(t-dx, t);
}
void reset(double &x, double &y, double &z)
{
long double t;
if (x>y)
{
t=x; x=y; y=t;
}
if (y>z)
{
t=y; y=z; z=t;
}
if (x>y)
{
t=x; x=y; y=t;
}
}
int main()
{
int cas;
double x,y,z;
double left, right;
scanf("%i",&cas);
for(int i=1;i<=cas;i++)
{
scanf("%lf %lf %lf %lf", &a, &b, &c, &d);
if (a<0)
{
a=-a; b=-b; c=-c; d=-d;
}
left = (-b-sqrt(b*b-3.0*a*c))/(3.0*a);
right = (-b+sqrt(b*b-3.0*a*c))/(3.0*a);
x = solve(left, right);
y = getpos(left, -1.0);
z = getpos(right, 1.0);
reset(x,y,z);
printf("Case %i: %.3lf %.3lf %.3lf/n", i, x, y, z);
}
return 0;
}


发现数学蛮难蛮麻烦的……以后可怎么过……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: