1. 程式人生 > >bzoj1007 [HNOI2008]水平可見直線——單調棧

bzoj1007 [HNOI2008]水平可見直線——單調棧

LG tps geo while 可見 i++ HP 斜率 zoj

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=1007

可以把直線按斜率從小到大排序,用單調棧維護,判斷新直線與棧頂的交點和棧頂與它之前直線的交點的位置關系即可。

代碼如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const maxn=50005;
int n,top,ans[maxn];
struct N{
    double a,b;
    
int bh; }p[maxn],sta[maxn]; bool vis[500005]; bool cmp(N x,N y) { if(x.a!=y.a)return x.a<y.a; else return x.b>y.b; } bool pd(N a) { N b=sta[top],c=sta[top-1]; double x1=(c.b-b.b)/(b.a-c.a); double x2=(c.b-a.b)/(a.a-c.a); if(x2<=x1)return 1; else return 0; } int main() { scanf(
"%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf",&p[i].a,&p[i].b),p[i].bh=i; sort(p+1,p+n+1,cmp); for(int i=1;i<=n;i++) { if(p[i].a==p[i-1].a)continue; while(top>1&&pd(p[i]))top--; sta[++top]=p[i];ans[top]=p[i].bh; } sort(ans
+1,ans+top+1); for(int i=1;i<=top;i++) printf("%d ",ans[i]); return 0; }

bzoj1007 [HNOI2008]水平可見直線——單調棧