bzoj 1007 计算几何,单调栈
tags:在纸上画画还是很容易看出的,可以看到的部分是一个半凸包,且随着交点横坐标增大时,直线斜率增加。所以这题只要按斜率排好序,再维护一个单调栈即可。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a;i<=b;i++) #define per(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define eps 1e-8 typedef long long ll; const int N = 5e4+10; struct Line{ int id; double a, b; friend bool operator < (const Line &a, const Line &b) { if(fabs(a.a-b.a)<eps) return a.b>b.b; return a.a<b.a; } }line[N]; int n, top, Stack[N<<2], ans[N]; double solve(int i, int j) { return (line[i].b-line[j].b)/(line[j].a-line[i].a); } int main() { scanf("%d", &n); rep(i,1,n) { scanf("%lf %lf", &line[i].a, &line[i].b); line[i].id=i; } sort(line+1, line+1+n); rep(i,1,n) if((i>1 && fabs(line[i].a-line[i-1].a)>eps) || i==1) { while(true) { if(top<=1) { Stack[top++]=i; break; } int nd=Stack[top-2], st=Stack[top-1]; double x1=solve(nd, st), x2=solve(st, i); if(x2<=x1) top--; else { Stack[top++]=i; break; } } } rep(i,0,top-1) ans[line[Stack[i]].id]=1; rep(i,1,n) if(ans[i]) printf("%d ", i); return 0; }