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\n"); 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\n",r); 37 } 38 return 0; 39 }