• 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
    ");
            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;
    }
  • 相关阅读:
    C#自己写的迭代器(拓展字典)
    C#中的浅复制和深复制
    C#中的委托和事件
    转载--《怎样制作一款优秀的塔防游戏》
    3D数学基础
    MonoBehaviour可重写的函数
    悲观锁及乐观锁
    java nio
    hadoop2.x通过Zookeeper来实现namenode的HA方案集群搭建-实践版
    oozie bundle学习笔记
  • 原文地址:https://www.cnblogs.com/max88888888/p/6744716.html
Copyright © 2020-2023  润新知