[P3743] kotori的设备 题解

今天做的第三道二分的题目。这次是在实数域上二分,犯了很多不必要的错误www

在实数域上二分要预先确定好精度 \(eps\) 。在这道题上,\(eps\le 10^{-5}\) 比较保险。

我们还是考虑二分答案。对于每一个二分到的答案,我们这样判定合法性:

  • 若设备已有的能量可以满足目前答案需要,忽略该设备。
  • 若设备已有的能量不能满足目前答案需要,那就用充电器充电到刚好满足为止。
  • 比较需要的能量总和和充电器最多提供的能量,没超过就合法,超过了就不合法。

所有设备的消耗能量速度总和小于充电器的充电速度,输出 \(-1\)

时间复杂度 O(n \log k) 。其中 \(k\) 是一个很大的数字。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps = 1e-5;
const int maxn = 1000005;
typedef double db;
int n;
double p, sum = 0;
db a[maxn], b[maxn];
bool check(db ans) {
	db maxx = p * ans;
	db real = 0.0;
	for(int i = 1; i <= n; i ++) {
		if(a[i] * ans <= b[i]) continue;
		real += a[i] * ans - b[i];
	} return real <= maxx;
}
int main() {
	cin >> n >> p;
	for(int i = 1; i <= n; i ++)  {
		cin >> a[i] >> b[i];
		sum += a[i];
	} if(sum <= p) return puts("-1") & 0;
	double l = 0.0, r = 1e10, mid;
	while(r - l > eps) {
		mid = (l + r) / 2;
		if(check(mid)) l = mid;
		else r = mid;
	} printf("%.10lf", l);
}
posted @ 2021-02-07 19:59  Inversentropir-36  阅读(93)  评论(0编辑  收藏  举报