Codeforces 801C Voltage Keepsake(二分枚举+浮点(模板))

题目链接:http://codeforces.com/contest/801/problem/C

题目大意:给你一些电器以及他们的功率,还有一个功率一定的充电器可以给这些电器中的任意一个充电,并且不计切换充电器的时间,问你最多能够同时使用这些充电器多久,如果可以一直用下去就返回-1。要求时间误差不能超过10^-4.

思路:开始没就见过这种类型的题目傻傻地一点一点把时间加上去。。。。后来知道这是用了二分枚举,首先定义一个右边界(r=1e11根据提目应该大于1e10多一点)和左边界(l=0),然后不断枚举中间时间,

判断是否符合条件,当左右边界时间差不超过题目要求时(这里定了1e-5),就可以跳出了。

  

 1 #include<iostream>
 2 using namespace std;
 3 const int N=1e5+5;
 4 struct node{
 5     int cost,time;
 6 }a[N];
 7 
 8 int main(){
 9     int n,add;
10     long long sum=0;
11     scanf("%d %d",&n,&add);
12     for(int i=1;i<=n;i++){
13         scanf("%d %d",&a[i].cost,&a[i].time);
14         sum+=a[i].cost; 
15     }
16     
17     if(sum<=add)//充电功率大于消耗功率总和,说明可以一直用下去 
18         printf("-1
");
19     else{
20         double l=0,r=1e11;
21         double t0=1e-5;
22         //二分枚举时间 
23         while(r-l>t0){//为了让时间精度大于1e-4; 
24             double mid=(l+r)/2;
25             double k=0;
26             for(int i=1;i<=n;i++){
27                 if(a[i].cost*mid>a[i].time){//如果当前的电量不够那就需要充电器 
28                     k+=(a[i].cost*mid-a[i].time)/add;//k值就是所需总充电时间,(a[i].cost*mid-a[i].time)/add表示是该电器使用mid秒所需充电时间 
29                 }
30             }
31             if(k>mid)
32                 r=mid;
33             else
34                 l=mid;
35         }
36         printf("%lf
",r);
37     }
38     return 0;    
39 } 
原文地址:https://www.cnblogs.com/fu3638/p/6724826.html