Codeforces Round #409 C

题意:给一个n,p,然后n行,每行2个数据ai表示第i个电池放电的速度,bi表示第i个电池原来有多少电量,p表示有充电器充电的速度(同一时间只能给一个电池充电),问最多能坚持多长时间使得所有的电池电量都步为0,如果是无穷输出-1

思路:二分时间,然后o(n)check求出是否可行,check: 求x=t*p 求出当前时间充电器一共可以充多少电,然后判断每个电池在当前时间需要多少电量,如果原有的电量不够那么用x来补充电量,如果最后x>=0 那么当前时间可行,反之步可行

AC代码:

#include "iostream"
#include "string.h"
#include "stack"
#include "queue"
#include "string"
#include "vector"
#include "set"
#include "map"
#include "algorithm"
#include "stdio.h"
#include "math.h"
#define ll long long
#define bug(x) cout<<x<<" "<<"UUUUU"<<endl;
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
#define eps 1e-6
const int N=1e5+100;
int p,n;
ll sum=0,sum0=0;
double a[N],b[N];
bool check(double mid){
    double s=mid*p;
    for(int i=0; i<n; ++i){
        double x=a[i]*mid;
        if(b[i]<x){
            s-=(x-b[i]);
        }
        if(s<0) return 0;
    } //bug("UUU");
    return 1;
}
int main(){
    int x,y;
    scanf("%d%d",&n,&p);
    for(int i=0; i<n; ++i){
        scanf("%d%d",&x,&y);
        a[i]=1.0*x;
        b[i]=1.0*y;
        sum+=x;
        sum0+=y;
    }//cout<<sum0<<endl;
    if(sum<=p){
        printf("-1\n");
        return 0;
    }
    double l=0,r=1.0*sum0/(1.0*(sum-p)),ans=0; //cout<<r<<endl;
    while(fabs(l-r)>eps){
        double mid=(l+r)/2;
        if(check(mid)) ans=mid,l=mid+eps;
        else r=mid-eps;
    }
    cout<<ans<<endl;
    return 0;
}

 

posted on 2017-04-21 17:41  lazzzy  阅读(168)  评论(0编辑  收藏  举报

导航