【BZOJ1007】[HNOI2008]水平可见直线
【BZOJ1007】[HNOI2008]水平可见直线
题面
题解
这题是用来搞笑的吧。。。
一眼看来就是半平面交啊,结果发现是个弱化版半平面交。
就按照半平面交的方法就行了。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 5e4 + 5;
struct Line { int k, b, id; } ;
bool operator < (const Line &l, const Line &r)
{ return l.k == r.k ? l.b > r.b : l.k < r.k; }
double Intersection(Line &l, Line &r)
{ return 1.0 * (l.b - r.b) / (r.k - l.k); }
bool cmp_i(const Line &l, const Line &r) { return l.id < r.id; }
int N;
Line l[MAX_N], stk[MAX_N];
int main () {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
N = gi(); for (int i = 1; i <= N; i++) l[i] = (Line){gi(), gi(), i};
sort(&l[1], &l[N + 1]);
l[0].k = -1e9;
int cnt = 0;
for (int i = 1; i <= N; i++) if (l[i].k != l[i - 1].k) l[++cnt] = l[i];
N = cnt;
int top = 0;
stk[++top] = l[1];
for (int i = 2; i <= N; i++) {
while (top > 1 && Intersection(l[i], stk[top]) <= Intersection(l[i], stk[top - 1])) --top;
stk[++top] = l[i];
}
sort(&stk[1], &stk[top + 1], cmp_i);
for (int i = 1; i <= top; i++) printf("%d ", stk[i].id);
printf("\n");
return 0;
}