codeforces#1011C. Fly (二分,注意精度)

题意:火箭经过1到n号星球,并回到1号星球,现在给出每消耗一砘燃油能带起的火箭质量a[i]和b[i],a[i]代表在第i个星球起飞,b[i]代表在第i个星球降落。求出最少消耗的汽油。保证:如果不能完成旅行,那么输出-1,如果有解,那么解一定小于1e9

分析:将答案从0到1e9二分,但是如何判断有没有解呢?我的做法是把1e9带入check函数,但是由于true和false的界线在正确解的附近,所以当1e9是正确解的时候,check函数返回的可能是false。解决方法是,将答案在0到2e9之间二分,如果是无解,那么会将答案二分到2e9,如果解大于1e9,那么我们在最后判断二分的结果是否大于1e9,解比1e9大0.000001也没关系,因为题目给了精度误差,而且true与false的界线与正确解的界线误差是不会大于0.000001的

 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000+10;
int n,m;
double a[maxn],b[maxn];
bool check(double x)
{
    if(x>=(x+m)/a[1])x-=(x+m)/a[1];
    else return false;
    for(int i=2;i<=n;i++)
    {
        if(x>=(x+m)/b[i])x-=(x+m)/b[i];
        else return false;
        if(x>=(x+m)/a[i])x-=(x+m)/a[i];
        else return false;
    }
    if(x>=(x+m)/b[1])x-=(x+m)/b[1];
    else return false;
    return true;
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%lf",&a[i]);
    for(int i=1;i<=n;i++)
        scanf("%lf",&b[i]);
    double st=0,en=2e9;
    for(int i=1;i<=100;i++)
    {
        double md=(st+en)/2;
        if(check(md))en=md;
        else st=md;
    }
    if(st<1e9+0.000001)
       printf("%.12f\n",st);
    else
       printf("-1\n");
    return 0;
}

  

posted @ 2019-03-03 16:48  czh~  阅读(246)  评论(0编辑  收藏  举报