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

洛谷傳送門

Codeforces傳送門

題目大意

給你nn種工作, 第ii種每天能給你aia_iaa值, bib_ibb值, 每種工作可以做任意時間, 求要達到ppaa值和qqbb值至少需要多少天。

解題分析

很明顯, 把(ai,bi)(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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章