Codeforces Round #409 C
题意:给一个n,p,然后n行,每行2个数据ai表示第i个电池放电的速度,bi表示第i个电池原来有多少电量,p表示有充电器充电的速度(同一时间只能给一个电池充电),问最多能坚持多长时间使得所有的电池电量都步为0,如果是无穷输出-1
思路:二分时间,然后o(n)check求出是否可行,check: 求x=t*p 求出当前时间充电器一共可以充多少电,然后判断每个电池在当前时间需要多少电量,如果原有的电量不够那么用x来补充电量,如果最后x>=0 那么当前时间可行,反之步可行
AC代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a) memset(a,0,sizeof(a)) using namespace std; #define eps 1e-6 const int N=1e5+100; int p,n; ll sum=0,sum0=0; double a[N],b[N]; bool check(double mid){ double s=mid*p; for(int i=0; i<n; ++i){ double x=a[i]*mid; if(b[i]<x){ s-=(x-b[i]); } if(s<0) return 0; } //bug("UUU"); return 1; } int main(){ int x,y; scanf("%d%d",&n,&p); for(int i=0; i<n; ++i){ scanf("%d%d",&x,&y); a[i]=1.0*x; b[i]=1.0*y; sum+=x; sum0+=y; }//cout<<sum0<<endl; if(sum<=p){ printf("-1\n"); return 0; } double l=0,r=1.0*sum0/(1.0*(sum-p)),ans=0; //cout<<r<<endl; while(fabs(l-r)>eps){ double mid=(l+r)/2; if(check(mid)) ans=mid,l=mid+eps; else r=mid-eps; } cout<<ans<<endl; return 0; }