码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 1007 水平可见直线

时间:2019-02-16 19:25:57      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:ble   code   1.0   sort   pac   while   online   space   ==   

bzoj 1007 水平可见直线

  • 这里的半平面都是 \(y\geq 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 水平可见直线

标签:ble   code   1.0   sort   pac   while   online   space   ==   

原文地址:https://www.cnblogs.com/jklover/p/10388839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!