题意
You have n devices that you want to use simultaneously.
The i-th device uses
You have a single charger that can plug to any single device. The charger will add p units of power per second to a device. This charging is continuous. That is, if you plug in a device for λ seconds, it will gain λ·p units of power. You can switch which device is charging at any arbitrary unit of time (including real numbers), and the time it takes to switch is negligible.
You are wondering, what is the maximum amount of time you can use the devices until one of them hits 0 units of power.
If you can use the devices indefinitely, print -1. Otherwise, print the maximum amount of time before any one device hits 0 power.
给定 n 台机器同时使用,第 i 台机器每秒消耗能量
若 n 台机器能够无限工作,输出 -1
。
解题思路
当且仅当
二分进行枚举能够同时工作 t 秒,再对 t 秒判断每台机器是否都能够坚持 t 秒钟。
判断 n 台机器是否能坚持至少 t 秒:在 t 秒时间充电器能够充能量总值为
代码
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
int n;
double p, a[100010], b[100010];
bool jug(double t)
{
double ext = p * 1.0 * t;
double sub;
for(int i=1;i<=n;i++)
{
sub = a[i] * t - b[i];
if(sub > 0) ext -= sub;
if(ext < 0) return false;
}
return true;
}
int main()
{
double sum = 0;
scanf("%d %lf",&n,&p);
for(int i=1;i<=n;i++)
scanf("%lf %lf",&a[i],&b[i]), sum += a[i];
if((p - sum) >= -eps){
printf("-1\n");
return 0;
}
double l = 0, r = 1e12, mid, ans;
while((r-l) > eps)
{
mid = (l+r)/2;
if(jug(mid))
l = mid, ans = mid;
else
r = mid;
}
printf("%.8lf\n", ans);
}
/*
针对这段代码可能出现在 32 位编译器中用下列样例将进入死循环的情况,可以考虑将 eps 改为 1e-6,或在 64 位编译器下运行。
原因: 32 位编译器下 double 的有效数字仅在 15 位左右。
Sample:
25000 49999
2 99999
2 99999
2 99999
...
2 99999
正统做法:由于 double 的有效位数有限以及本题答案较大,在 1e-4 的相对精度下,限制二分次数 100 次左右可以保证达到精度要求且时间较短。
*/