codeforces 801C Voltage Keepsake

题目链接: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 }
View Code

 

posted @ 2017-05-30 20:46  BadboyQAQ  阅读(163)  评论(0编辑  收藏  举报