题目链接:http://codeforces.com/contest/801/problem/C
题意:给你n个设备,还有一个充电器,充电器功率为P,每秒可以充P的电,充电器每次可以给一个设备充电,忽略拔插时间。每个设备每一秒消耗ai的电,它目前有bi的电。问你这些设备在用这个充电器的情况下最多能工作多久(一个设备的电变为0即为不能工作),如果可以永久工作输出-1。
分析:看到-1就先考虑-1的情况,就是所有设备每秒消耗的电的总和小于等于充电器的P,那么就可以永久工作了。对于n个设备的工作时间,我们应该考虑他之所以不能工作,是因为P功率的充电器无法满足所有设备的需求,他之所以能工作一段时间是因为它原本有电。因此如果在tt时刻设备不能工作,那么他在以后的时间也肯定不能工作。我们可以二分工作时间,利用充电器充的电P*t和设备电的消耗的关系,算出最长工作时间。需要注意二分的上界,我0x4个3fwa了,然后胡搞0x6个3f过了,一直对这个不太懂,还是开1e18比较靠谱。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct st{ 4 int x,y; 5 }a[1000005]; 6 int main() { 7 long long n,p; 8 cin>>n>>p; 9 long long sum1=0; 10 long long sum2=0; 11 for(int i=1;i<=n;i++){ 12 cin>>a[i].x>>a[i].y; 13 sum1+=a[i].x; 14 sum2+=a[i].y; 15 } 16 if(sum1<=p){ 17 cout<<-1<<endl; 18 } 19 else { 20 double low=0,high=0x3f3f3f3f3f3f; 21 double ans; 22 while(high-low>0.00000001){ 23 double mid=(low+high)/2.0; 24 double sum=mid*p; 25 for(int i=1;i<=n;i++){ 26 if(a[i].y-a[i].x*mid<0){ 27 sum=sum-(a[i].x*mid-a[i].y); 28 if(sum<0) break; 29 } 30 } 31 if(sum>0){ 32 ans=mid; 33 low=mid+0.00000001; 34 } 35 else { 36 high=mid-0.00000001; 37 } 38 } 39 printf("%.8lf\n",ans); 40 } 41 return 0; 42 }