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, 才可以这样做。
如果没有差距这个限制可能就得重新考虑一下。如果存在相同的解那我就……
发现数学蛮难蛮麻烦的……以后可怎么过……
一道解一元三次方程的题目。训练时没有做出来。
解题代码过来后看了一下。着实是不知道里面是怎么计算的,但是结果又是对的。
就着那个代码提交了两次还是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; }
发现数学蛮难蛮麻烦的……以后可怎么过……
相关文章推荐
- 【2031】求一元三次方程的解
- nyoj 1178 && hdu 5105 Math Problem 求解一元二次三次方程
- zstu2462 求一元三次方程的根
- hdu5105(求一元三次方程的最值)
- EXCEL 单变量求解 解一元三次方程
- 用弦截法求一元三次方程的根
- 一元三次和四次方程的解
- codeves天梯 解一元三次方程
- 弦截法求一元三次方程的近似解
- 三分求一元三次方程的极值:hdu 4355
- 第九周任务02:求一元二次方程的解
- 第三章数程序设计初步--分支结构项目5求一元二次方程的根
- 用“派生类”求一元二次方程的解
- 39.输入任意的a,b,c求一元二次方程ax*x+bx+c=0的根
- 一元方程的数值解法
- 一元高次方程的求解
- 求一元二次方程
- 分支-18. 求一元二次方程的根*
- C 求一元二次方程的解
- 通过java实现输入系数求一元二次方程根,学习Scanner()、split()和Substring()函数