• Codeforces 801C Voltage Keepsake


      1.因为充电器在任意时刻给任意机器充电,并且交换充电对象并不消耗时间,所以可以从整体来看,如果充电器每秒可以冲的电量p大于等于全部机器的每秒消耗的电量的话,相当于可以利用充电器做到,让每台机器的电量始终大于等于它的原电量,也就是每台机器电量只可能增不可能减,所以可以无限使用下去。2.若不能无限的使用下去的话,因为使用的时间越长,出现某个机器电量为0的概率就越大可以理解为1111000000(1代表可以使用到该时刻,0代表不能使用到该时刻)可以看出具有单调性,那就通过二分求出能使用的最长时间。二分的话主要就是要考虑check函数,按每个机器不充电能使用到的最大时间排个序,然后依次取到mid时刻,详细的见注释。

    #include<bits/stdc++.h>
    using namespace std;
    #define eps 1e-7
    struct node
    {
        double a,b,time;
    }ma[1000000+10];
    double p;
    int n;
    bool cmp(const node&a,const node&b)
    {
        return a.time<b.time;
    }
    bool check(double mid)
    {
        double tmp=0;
        for(int i=0;i<n;i++)
        {
            if(ma[i].time>mid) break;
            tmp+=(mid-ma[i].time)*ma[i].a;//因为要判断能不能使用到mid时刻,所以要把在mid时刻之前就没电的机器充上电才行,这步操作是计算给这些没电了的机器充电需要消耗的电量。
        }
        return mid*p>=tmp;若充电器能提供的电量>=需要的电量则mid满足
    }
    int  main()
    {
        double tmp=0;
        cin>>n>>p;
        for(int i=0;i<n;i++)
        {
            cin>>ma[i].a>>ma[i].b;
            ma[i].time=ma[i].b/ma[i].a;
            tmp+=ma[i].a;
    
        }
        if(p>=tmp)
        {
            cout<<-1<<endl;
            return 0;
        }
        sort(ma,ma+n,cmp);
        double low=0,up=1e11+100,mid;//这个上限我一开始开小了,过不了,看了别人的就改大过了
        while(up-low>=eps)
        {
            mid=(low+up)/2;
            if(check(mid))
                low=mid;
            else
                up=mid;
        }
        printf("%.10lf
    ",low);
        return 0;
    }
    
  • 相关阅读:
    OSI结构和TCP/IP模型
    将[4,3,2,5,4,3]分割成[4,3,2]、[5,4,3]两个List的算法
    Mybatis增加对象属性不增加mapper.xml的情况
    以脚本方式直接执行修改密码的passwd命令
    Raphael的鼠标over move out事件
    Raphael的Braille例子
    Raphael的set使用
    Raphael的transform用法
    Raphael的text及对齐方式
    Raphael初始化,path,circle,rect,ellipse,image
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754947.html
Copyright © 2020-2023  润新知