zoukankan      html  css  js  c++  java
  • BZOJ 1007: [HNOI2008]水平可见直线 栈/计算几何

    1007: [HNOI2008]水平可见直线

    Time Limit: 1 Sec  Memory Limit: 162 MB

    题目连接

    http://www.lydsy.com/JudgeOnline/problem.php?id=1007

    Description

     在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的.
        例如,对于直线:
        L1:y=x; L2:y=-x; L3:y=0
        则L1和L2是可见的,L3是被覆盖的.
        给出n条直线,表示成y=Ax+B的形式(|A|,|B|<=500000),且n条直线两两不重合.求出所有可见的直线.

    Input

    第一行为N(0 < N < 50000),接下来的N行输入Ai,Bi

    Output

    从小到大输出可见直线的编号,两两中间用空格隔开,最后一个数字后面也必须有个空格

    Sample Input

    3
    -1 0
    1 0
    0 0

    Sample Output

    1 2

    HINT

    题解:

    首先我们按照斜率从大到小排序,然后我们对一个堆进行优化

    如果要插入一条直线的话,K最大的那条线和K最小的肯定不会背盖住,只会有中间的那条直线被压住

    所以我们就判定一下,然后不停的更新就好了

    具体判定是看 斜率小的直线与斜率中间的直线,斜率小的直线和斜率大的直线,这两个x的坐标大小进行比较,然后就可以啦~

    代码:

    //qscqesze
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    typedef long long ll;
    using namespace std;
    //freopen("D.in","r",stdin);
    //freopen("D.out","w",stdout);
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define maxn 50001
    #define mod 10007
    #define eps 1e-9
    //const int inf=0x7fffffff;   //无限大
    const int inf=0x3f3f3f3f;
    /*
    
    */
    //**************************************************************************************
    struct node
    {
        double x,y;
        int id;
    };
    bool cmp(node c,node d)
    {
        return c.x>d.x;
    }
    double kiss(node a,node b)
    {
        return (b.y-a.y+0.0)/(a.x-b.x+0.0);
    }
    node a[maxn],aa[maxn];
    int s[maxn];
    inline ll read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    bool cmp2(int c,int d)
    {
        return a[c].id<a[d].id;
    }
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>aa[i].x>>aa[i].y;
            aa[i].id=i;
        }
        sort(aa+1,aa+n+1,cmp);
        int M=0;
        for(int i=1;i<=n;i++)
        {
            if(aa[i].x!=a[i-1].x) 
                a[++M]=aa[i];
            else if(aa[i].y>a[M].y) 
                a[M].y=aa[i].y,a[M].id=aa[i].id;            
        }
        int top=0;
        s[1]=1;top=1;
        for(int i=2;i<=M;i++)
        {
            while(top>=2)
            {
                double x1=kiss(a[s[top-1]],a[i]);
                double x2=kiss(a[s[top]],a[i]);
                if(x1<=x2+1e-6)
                    top--;
                else
                    break;
            }
            s[++top]=i;
        }
        sort(s+1,s+top+1,cmp2);
        for(int i=1;i<=top;i++)
            cout<<a[s[i]].id<<" ";
        return 0;
    }
  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4381935.html
Copyright © 2011-2022 走看看