BZOJ 1007 [HNOI2008]水平可见直线

来源:互联网 发布:浙师大行知学院新生 编辑:程序博客网 时间:2024/05/18 23:14

最后所有可见直线形成的,一定是类似下凸壳的东西,从左到右斜率递增。

将所有直线按照斜率从小到大排序,依次遍历分情况入栈。一条直线会把前一条直线覆盖,当且仅当该直线斜率比前一条直线大(排序后一定满足),且直线在栈中前两条直线的交点之上。这样也就是在维护一个下凸壳。

#include<cstdio>#include<algorithm>#include<cmath>#define MAXN 50005using namespace std;struct line{double k, b;int id;}l[MAXN];double eps=1e-7;bool cmp(line a, line b){return a.k<b.k||(fabs(a.k-b.k)<eps&&a.b<b.b);}double crossx(line a, line b){return (b.b-a.b)/(a.k-b.k);}int S[MAXN], top=0, ans[MAXN];int main(){    int n;    scanf("%d",&n);    for(int i = 1; i <= n; i++)    {        scanf("%lf%lf",&l[i].k,&l[i].b);        l[i].id=i;    }    sort(l+1,l+n+1,cmp);    for(int i = 1; i <= n; i++)    {        while(top)        {            if(fabs(l[S[top-1]].k-l[i].k)<eps)top--;            else if(top>1&&crossx(l[i],l[S[top-1]])<=crossx(l[S[top-2]],l[S[top-1]]))top--;            else break;        }        S[top++]=i;    }    for(int i = 0 ; i < top; i++)        ans[l[S[i]].id]=1;    for(int i = 1; i <= n; i++)        if(ans[i])            printf("%d ",i);    return 0;}
1 0
原创粉丝点击