洛谷传送门
Codeforces传送门
题目大意
给你 n n n种工作, 第 i i i种每天能给你 a i a_i ai点 a a a值, b i b_i bi点 b b b值, 每种工作可以做任意时间, 求要达到 p p p点 a a a值和 q q q点 b b b值至少需要多少天。
解题分析
很明显, 把 ( a i , b i ) (a_i,b_i) (ai,bi)放在图上, 我们每天可以得到的能力值一定在这些点形成的凸包里面, 于是二分答案就好了。
代码如下:
#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);
}