uvaoj10341
Solve the equation:
p ∗ e −x + q ∗ sin(x) + r ∗ cos(x) + s ∗ tan(x) + t ∗ x 2 + u = 0
where 0 ≤ x ≤ 1.
Input
Input consists of multiple test cases and terminated by an EOF. Each test case consists of 6 integers in
a single line: p, q, r, s, t and u (where 0 ≤ p, r ≤ 20 and −20 ≤ q,s,t ≤ 0). There will be maximum
2100 lines in the input file.
Output
For each set of input, there should be a line containing the value of x, correct up to 4 decimal places,
or the string ‘No solution’, whichever is applicable.
Sample Input
0 0 0 0 -2 1
1 0 0 0 -1 2
1 -1 1 -1 -1 1
Sample Output
0.7071
No solution
0.7554
------------------------------------------------------------------------------------------------
这个题,让我非常的无奈!精确度一定要把握好!!!!!
题目分析:
这个题一看输出有小数点,就大概知道考点了,几乎就是猜数了,就是二分法来带入使之符合 方程的解 。方程值大了,小了,那么二分法取值做出相应的改变。
那么,重要的就是这个方程了,这个方程的关键信息来源于p,q,r,u,s的正负,题目已经明确给出了!!
p ∗ e (−x) + q ∗ sin(x) + r ∗ cos(x) + s ∗ tan(x) + t ∗ x *x
x越大,p ∗ e (−x)越小,r ∗ cos(x)越小,而且都>0。 q ∗ sin(x) , s ∗ tan(x) ,t ∗ x *x越大,且都<0.
正(减函数) + 负(增函数)-〉所以函数整体是一个减函数
x越大,函数值越小。这样确定了二分法的 取值变化。
------------------------------------------------------------------------------------------------
易错点1:
若程序总是WA。你们先带这两组数据看看
0 0 0 0 0 1
0 0 0 0 0 -1
输出应该都是 No solution 。
这是边界极限,x不管无限趋近0(或 1) ,函数值仍然大于0(或小于0)的情况,试一下。
就这两种极限,所以可以这样卡条件:
先判断
if(check(0)>0 || check(1)<0)
{
printf("No solution\n");
continue;
}
也可以这样,最后去判断
if(fabs(check(mid)-0.0)<1e-6)
printf("%.4f\n",mid);
else
printf("No solution\n");
易错点2:
谁用的是high-low>1e-6做的循环条件,就会wrong answer! 不精确 !本以为输出结果是小数点后四位,就确定到1e-6即可了,带了N次一直WA ,快撞墙了 ,但是忘了high 与 low 应无限接近相减几乎为0 1e-8
较精确,一改便通过了
while(high-low>1e-8) { mid = (high + low)/2; if(check(mid) > 0 )low = mid; else high = mid ; }
或者直接让它循环100次,绝对精确!
low = 0; high = 1; for(i=0;i<100;i++) { mid = (low+high)/2; if(check(mid)>0)low = mid; else high =mid; }
-------------------------------------------------------------------------------------------------------------------
接下来就是整体代码了 ,放了两种。
这种RUN Time 0.006!
#include<stdio.h> #include<math.h> int p,q,r,s,t,u; double check(double x) { return p*exp(x*-1)+q*sin(x)+r*cos(x)+s*tan(x)+t*x*x + u ; } int main() { double mid , low = 0,high = 1; while(scanf("%d %d %d %d %d %d",&p,&q,&r,&s,&t,&u)!=EOF) { low = 0;high = 1; while(high-low>1e-8) { mid = (high + low)/2; if(check(mid) > 0 )low = mid; else high = mid ; } if(fabs(check(mid)-0.0)<1e-6) printf("%.4f\n",mid); else printf("No solution\n"); } return 0; }这种Run Time 0.026
#include<stdio.h> #include<math.h> int p,q,r,s,t,u; double check(double x) { return p*exp(x*-1)+q*sin(x)+r*cos(x)+s*tan(x)+t*x*x+u; } int main() { double low,mid,high; int i; while(scanf("%d %d %d %d %d %d",&p,&q,&r,&s,&t,&u)!=EOF) { low = 0; high = 1; for(i=0;i<100;i++) { mid = (low+high)/2; if(check(mid)>0)low = mid; else high =mid; } if(fabs(check(mid)-0.0)<1e-6) printf("%.4f\n",mid); else printf("No solution\n"); } return 0; }