codeforces 801C Voltage Keepsake

題目連接:http://codeforces.com/contest/801/problem/Cc++

題意:給你n個設備,還有一個充電器,充電器功率爲P,每秒能夠充P的電,充電器每次能夠給一個設備充電,忽略拔插時間。每一個設備每一秒消耗ai的電,它目前有bi的電。問你這些設備在用這個充電器的狀況下最多能工做多久(一個設備的電變爲0即爲不能工做),若是能夠永久工做輸出-1。ide

分析:看到-1就先考慮-1的狀況,就是全部設備每秒消耗的電的總和小於等於充電器的P,那麼就能夠永久工做了。對於n個設備的工做時間,咱們應該考慮他之因此不能工做,是由於P功率的充電器沒法知足全部設備的需求,他之因此能工做一段時間是由於它本來有電。所以若是在tt時刻設備不能工做,那麼他在之後的時間也確定不能工做。咱們能夠二分工做時間,利用充電器充的電P*t和設備電的消耗的關係,算出最長工做時間。須要注意二分的上界,我0x4個3fwa了,而後胡搞0x6個3f過了,一直對這個不太懂,仍是開1e18比較靠譜。spa

AC代碼:code

 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
相關文章
相關標籤/搜索