BZOJ-1007 水平可见直线
简单几何题。。。用个栈维护当前可见直线,然后通过判断三直线的交点的左右即可进行选择。
#include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <fstream> #include <iostream> #include <queue> #define rep(i, l, r) for(int i=l; i<=r; i++) #define N 56789 #define MAX 1<<30 #define clr(x, c) memset(x, c, sizeof(x)) #define ll long long using namespace std; int read() { ll x=0, f=1; char ch=getchar(); while (ch<'0' || ch>'9') { if (ch=='-') f=-1; ch=getchar(); } while (ch>='0' && ch<='9') { x=x*10+ch-'0'; ch=getchar(); } return x*f; } struct node{ll a, b, n;} c[N], v[N]; int n, vv; bool cmp(node a, node b) { return a.a<b.a || (a.a==b.a && a.b>b.b); } bool cmp2(node a, node b) { return a.n<b.n; } int main() { n=read(); rep(i, 1, n) c[i].a=read(), c[i].b=read(), c[i].n=i; sort(c+1, c+1+n, cmp); v[vv=1]=c[1]; rep(i, 2, n) if (c[i].a != c[i-1].a) { while (vv>1 && (v[vv].a-c[i].a)*(v[vv].b-v[vv-1].b) >= (v[vv-1].a-v[vv].a)*(c[i].b-v[vv].b)) vv--; v[++vv]=c[i]; } sort(v+1, v+1+vv, cmp2); rep(i, 1, vv) printf("%lld ", v[i].n); return 0; }