题意:火箭经过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 ",st); else printf("-1 "); return 0; }