[Codeforces Round #335 (Div. 1)] - C Freelancer's Dreams

版权声明:欢迎转载蒟蒻博客,但请注明出处: https://blog.csdn.net/LPA20020220/article/details/88558822

洛谷传送门

Codeforces传送门

题目大意

给你 n n 种工作, 第 i i 种每天能给你 a i a_i a a 值, b i b_i b b 值, 每种工作可以做任意时间, 求要达到 p p a a 值和 q q b b 值至少需要多少天。

解题分析

很明显, 把 ( a i , b i ) (a_i,b_i) 放在图上, 我们每天可以得到的能力值一定在这些点形成的凸包里面, 于是二分答案就好了。

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#define R register
#define IN inline
#define W while
#define gc getchar()
#define ll long long
#define db long double
#define EPS 1e-15
#define MX 100500
template <class T> IN T max(T a, T b) {return a > b ? a : b;}
template <class T> IN T min(T a, T b) {return a < b ? a : b;}
int n, x, y, cnum;
db curx, cury;
int conv[MX];
struct Point {db x, y;}dat[MX];
IN Point operator + (const Point &x, const Point &y) {return {x.x + y.x, x.y + y.y};}
IN Point operator - (const Point &x, const Point &y) {return {x.x - y.x, x.y - y.y};}
IN db operator * (const Point &x, const Point &y) {return x.x * y.y - x.y * y.x;}
IN bool operator < (const Point &x, const Point &y) {return x.x == y.x ? x.y < y.y : x.x < y.x;}
IN void Getconv()
{
	std::sort(dat + 1, dat + 1 + n);
	for (R int i = 1; i <= n; ++i)
	{
		W (cnum >= 2 && (dat[conv[cnum]] - dat[conv[cnum - 1]]) * (dat[i] - dat[conv[cnum - 1]]) <= 0) --cnum;
		conv[++cnum] = i;
	}
	int lim = cnum;
	for (R int i = n - 1; i; --i)
	{
		W (cnum > lim && (dat[conv[cnum]] - dat[conv[cnum - 1]]) * (dat[i] - dat[conv[cnum - 1]]) <= 0) --cnum;
		conv[++cnum] = i;
	}
	if (n > 1) --cnum;
}
IN bool check()
{
	Point cur = {curx, cury};
	for (R int i = 2; i <= cnum; ++i)
	if ((dat[conv[i]] - dat[conv[i - 1]]) * (cur - dat[conv[i - 1]]) < 0) return false;
	if ((dat[conv[1]] - dat[conv[cnum]]) * (cur - dat[conv[cnum]]) < 0) return false;
	return true;
}
int main(void)
{
	scanf("%d%d%d", &n, &x, &y);
	db l = 0, r = 1e6, mid, mxx = 0, mxy = 0;
	for (R int i = 1; i <= n; ++i)
	{
		scanf("%Lf%Lf", &dat[i].x, &dat[i].y);
		mxx = max(mxx, dat[i].x);
		mxy = max(mxy, dat[i].y);
	}
	dat[++n] = {0, 0};
	dat[++n] = {mxx, 0};
	dat[++n] = {0, mxy};
	Getconv();
	W (r - l > EPS)
	{
		mid = (l + r) / 2.0;
		curx = x * mid, cury = y * mid;
		if (check()) l = mid;
		else r = mid; 
	}
	printf("%.8Lf", 1.0 / mid);
}

猜你喜欢

转载自blog.csdn.net/LPA20020220/article/details/88558822