1007: [HNOI2008]水平可见直线

//因为要求的是从上方看下来可以看到的直线
//画一下图可以发现能看见的是上边的一个下凸壳 
//然后就单调栈维护一下斜率就好了 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=5e4+5;

int n;
struct LINE
{
    double a,b;
    int id;
}l[N],sta[N];
int top;

bool cmp1(LINE A,LINE B)
{
    return (A.a==B.a)?A.b<B.b:A.a<B.a;
}

bool cmp2(LINE A,LINE B)
{
    return A.id<B.id;
}

double calc(LINE x,LINE y)
{
    return (x.b-y.b)/(y.a-x.a);
}

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%lf%lf",&l[i].a,&l[i].b);
        l[i].id=i;
    }
    sort(l+1,l+n+1,cmp1);
    for(int i=1;i<=n;++i)
    {
        while(top>=1&&l[i].a==sta[top].a||top>=2&&calc(l[i],sta[top])<=calc(sta[top],sta[top-1]))
            --top;
        sta[++top]=l[i];
    }
    sort(sta+1,sta+top+1,cmp2);
    for(int i=1;i<=top;++i)
        cout<<sta[i].id<<' ';
    return 0;
}
原文地址:https://www.cnblogs.com/lovewhy/p/9633687.html