【洛谷P3743 kotori的设备】

/*
    24/2/3
    洛谷P3743 kotori的设备    
    //二分 感觉好难!! 
    
    //题意:n个设备 , 每个设备初始能量bi,每秒消耗ai个单位, 充电宝可令一个设备每秒充电p个单位 
    
    //思路:时间最长是多少 一定满足比答案小的时间都满足让设备大于0, 而比答案大的时间会让设备小于0
    //故进行二分答案 左边界为0 设时间为k,“右边界可以 max(bi + k * (p/n) - k * ai  = 0)当所有的等式的时间 != 0 则可无限使用” × 
    
    //后来发现想复杂了 直接在时间为k 时 先判断 bi >= ai *k 若满足则不用给其充电; 否则要充的电量为 ai * k - bi
    //将所有相加 再判断其和充电宝一共能提供的电量(p * k)的大小关系 
    
    错误 :右边界直接放1e10 就ok 
*/

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;

const int N = 1e6;

int n,p;
pair<int,int>s[N];

bool check(double x){
    double total = 0;
    double sum = x * p; //相应时间提供的电量
    for(int i = 0 ; i <n; i++){
        if(s[i].first * x <= s[i].second) continue;  //已有设备能量大于使用能量 
        
        total += (s[i].first*x - s[i].second);
    } 
    //cout << total << endl;
    if(total <= sum)
        return true;
    else
        return false;
}

double bsearch(double l, double r){

    while(r - l > 1e-6){
        double mid = (l + r)/2;
        if(check(mid)) l = mid;
        else r = mid;
    }
    return l;
}

int main(){
    scanf("%d%d",&n,&p);
    for(int i = 0; i < n; i++){
        cin >> s[i].first >> s[i].second;
    }
    sort(s,s+n);
    
    double k,r = -1;
    int count = 0;
    for(int i = 0; i < n; i++){
        
        if(p/n - s[i].first >= 0)
        {
            count++;
        }
        //r = max(r,s[i].second * 1.0/ (s[i].first - p / n));    
        
    }
    
    if(count == n)
    {
        cout << "-1" << endl;
    }
    else
    {
        double res =  bsearch(0,1e10);
        printf("%lf",res); 
        
    }
} 

//其实并不是太难 我还时太菜了 以后一定要想一下我右边界为什么会错 

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值