描述
题解
贪心可解,二分可解,前者更快更好,后者精度问题需要格外注意,另外需要强调的是要用long long
。
我一开始用的二分,一直存在精度问题解决不了,谁知道并不是我的精度错了,而是没有用long long
,结果当时没有找到这个问题,而选择用了贪心做,当然,同样的问题依然没有避免,经过仔细查找后发现是因为int
溢出了,用long long
后成功 AC。
说到贪心,这里用到了一个小小的数学变换:
设时间为t
,总能量为pz
,总消耗速度为v
,初始能量为pc
,则
t = pz / v = (pc + t * p) / (v - p + p) = pc / (v - p)
相当于分母消去了p
,分子消去了t * p
,没有什么难的,就是一个小技巧而已~~~
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1e5 + 10;
const int INF = 0x3f3f3f3f;
struct device
{
int a, b;
double c;
bool operator < (const device &b) const
{
return c < b.c;
}
} dev[MAXN];
int n, p;
int main(int argc, const char * argv[])
{
cin >> n >> p;
long long sum = 0;
for (int i = 0; i < n; i++)
{
scanf("%d%d", &dev[i].a, &dev[i].b);
dev[i].c = dev[i].b * 1.0 / dev[i].a;
sum += dev[i].a;
}
if (p >= sum)
{
cout << "-1\n";
return 0;
}
sort(dev, dev + n);
dev[n].c = INF;
long long sumA = 0, sumB = 0;
for (int i = 0; i < n; i++)
{
sumA += dev[i].a;
sumB += dev[i].b;
if (sumA <= p)
{
continue;
}
if (sumB * 1.0 / (sumA - p) <= dev[i + 1].c)
{
printf("%.10lf\n", sumB * 1.0 / (sumA - p));
return 0;
}
}
printf("%.10lf\n", sumB * 1.0 / (sumA - p));
return 0;
}