zoukankan      html  css  js  c++  java
  • BZOJ 1007 HNOI2008 水平可见的直线

    本来以为这是一道计算几何的题

    可看完题解发现。。。。。。

    单调栈即可

    按照a为第一关键字b为第二关键字从小到大排序

    再将最小的两条线入栈,然后依次处理每条线,如果其与栈顶元素的交点在上一个点的左边,则将栈顶元素出栈 

    为什么是对的呢,让我们来看这个图

    当我们不断往栈里加直线的时候,如果加入的直线与top-1的交点在top和top-1的交点左边,这样的话top的存在是没有任何意义的

    因为斜率是单调递增的,所以我们可以用单调栈来维护

    #include <bits/stdc++.h>
    #define eps 1e-8
    using namespace std; 
    const int MAXN=1e6+10;
    struct node{
        double a,b;
        int id;
    }e[MAXN],stark[MAXN];
    int n,top=0,vis[MAXN]={};
    inline bool mycmp(node n,node m){
        if(abs(n.a-m.a)<=eps) return n.b<m.b;
        else return n.a<m.a;
    }
    inline double cross(node xx,node yy){
        return (xx.b-yy.b)/(yy.a-xx.a);
    }
    inline void insert(node xx){
        while(top){
            if(abs(stark[top].a-xx.a)<=eps) top--;
            else if(top>1&&cross(xx,stark[top-1])<=cross(stark[top-1],stark[top])) top--;
            else break;
        }
        stark[++top]=xx;
    }
    void init(){
        cin>>n;
        for(int i=1;i<=n;i++){
            scanf("%lf%lf",&e[i].a,&e[i].b);
            e[i].id=i;
        }
        sort(e+1,e+n+1,mycmp);
    }
    void solve(){
        for(int i=1;i<=n;i++) insert(e[i]);
        for(int i=1;i<=top;i++){
            vis[stark[i].id]=1;
        }
        for(int i=1;i<=n;i++){
            if(vis[i]) printf("%d ",i);
        }
    }
    int main(){
        //freopen("All.in","r",stdin);
        //freopen("a.out","w",stdout);
        init();
        solve();
        return 0;
    }
    

    注意控制精度的问题

     
  • 相关阅读:
    QT 开发小记
    linux c 时间函数
    ubuntu 16.04 登录后黑屏
    ubuntu 16.04 修正网卡与ifname对应关系
    HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
    vue里面引入jq的方法
    如何禁用手机自带的输入法软键盘
    vue的首页渲染了两次的原因以及解决方法
    vue使用hightchats
    解决微信小程序使用switchTab跳转后页面不刷新的问题
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7853734.html
Copyright © 2011-2022 走看看