uva10341Solve It(二分+精度问题)

链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=113&page=show_problem&problem=1282

原题:
Solve the equation:
p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + 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 upto 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
感悟:
这个题窝第一次做的时候一看只保留4位小数 也就是说只有0.0000-1.0000 这 一万零一种情况,于是就想,如果有解那可能是其中之一。题目也没说如果有多组解应该怎么输出 那肯定只有一个解了。。。。想到这里,如果能枚举,肯定就可以二分。。于是这个函数肯定是个单调函数。。。只是枚举的话,将枚举的数与零比较的时候,无法准确判断正确答案,所以不能用枚举。
--------------------------
首先,泥得发现这是一个单调的函数,然后就可以用二分。。。但是发现wa的原因是精确度的问题。理论上 0.1234561 0.1234569 这俩数差值就小于1e-6,无论窝return哪一个答案都是一样的 可是,,,事实上窝错了。(r-l)<1e-6这个判断要改成 (r-l)<1e-7 甚至更小才能过。。。目前还在找原因,,先暂时搁置一下(:з」∠)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=1e4;
const double minc=1e-7;
// const double e=2.718281929;
double p,q,r,s,t,u;
double js(double x)
{
    return (p*exp(-x)+q*sin(x)+r*cos(x)+s*tan(x)+t*x*x+u); 
}
double erfen(double l,double r)
{
    if (r-l<minc) return l; 
    double mid=(l+r) /2.0;
    // double ansm=js(mid);ansl=js(l);
    if (js(mid)*js(l)>0) return erfen(mid,r);
    else return erfen(l,mid);
}
int main()
{

    freopen("in.txt","r",stdin);
    while(~scanf("%lf%lf%lf%lf%lf%lf",&p,&q,&r,&s,&t,&u))
    {
        // cout<<js(0)<<' '<<js(1)<<' ';
        if(js(1)*js(0)>0) 
        {
            printf("No solution\n");
        }
        else 
        {
            printf("%.4f\n",erfen(0,1));
        }

    }
    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值