bzoj1007 [HNOI2008]水平可见直线——单调栈

题目: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;
}

 

posted @ 2018-06-11 08:15  Zinn  阅读(143)  评论(0编辑  收藏  举报