bzoj 1007 水平可见直线

Posted jklover

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1007 水平可见直线相关的知识,希望对你有一定的参考价值。

bzoj 1007 水平可见直线

  • 这里的半平面都是 (ygeq kx+b) 类型的,将直线 (l:y=kx+b) 对应到点 ((k,-b)) ,转化成凸包求解即可.
  • 如果有两种类型,需分类后分别求上下凸包,最后去重,合并.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pii pair<int,int>
inline int read()
{
    int x=0;
    bool pos=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            pos=0;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return pos?x:-x;
}
const double eps=1e-10;
const int MAXN=5e4+10;
int n;
struct Line{
    int k,b;
    int id;
    bool operator < (const Line &rhs) const 
        {
            return (k<rhs.k)||(k==rhs.k&&b>rhs.b);
        }
    Line operator - (const Line &rhs) const
        {
            Line res;
            res.k=k-rhs.k;
            res.b=b-rhs.b;
            return res;
        }
}A[MAXN];
int stk[MAXN],tp=0;
double calck(Line x,Line y)
{
    return 1.0*(y.b-x.b)/(x.k-y.k);
}
int ans[MAXN];
int main()
{
    n=read();
    for(int i=1;i<=n;++i)
        {
            A[i].k=read();
            A[i].b=read();
            A[i].id=i;
        }
    sort(A+1,A+1+n);
    stk[++tp]=1;
    for(int i=2;i<=n;++i)
        if(A[i].k!=A[i-1].k)
            {
                while(tp>=2 && calck(A[i],A[stk[tp]])-calck(A[stk[tp]],A[stk[tp-1]])<=eps)
                    --tp;
                stk[++tp]=i;
            }   
    for(int i=1;i<=tp;++i)
        ans[i]=(A[stk[i]].id);
    sort(ans+1,ans+1+tp);
    for(int i=1;i<=tp;++i)
        printf("%d ",ans[i]);
    puts("");
    return 0;
}

以上是关于bzoj 1007 水平可见直线的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1007 水平可见直线

BZOJ 1007 水平可见直线 | 计算几何

BZOJ1007水平可见直线(单调栈)

BZOJ 1007: [HNOI2008]水平可见直线

bzoj 1007 [HNOI2008]水平可见直线(单调栈)

bzoj1007[HNOI2008]水平可见直线