zoukankan      html  css  js  c++  java
  • bzoj1007/luogu3194 水平可见直线 (单调栈)

    先按斜率从小到大排序,然后如果排在后面的点B和前面的点A的交点是P,那B会把A在P的右半段覆盖掉,A会把B在P的左半段覆盖掉。

    然后如果我们现在又进来了一条线,它跟上一条的交点还在上一条和上上条的左边,这就说明上一条完全被覆盖了

    这样的话,维护一个单调栈做一做就可以了

    (要先处理一下,斜率相同的只留下B最大的,而且会有重合的线,都要输出)

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define ll long long
     4 using namespace std;
     5 const int maxn=50050;
     6 
     7 ll rd(){
     8     ll x=0;char c=getchar();int neg=1;
     9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    11     return x*neg;
    12 }
    13 
    14 struct Line{
    15     int a,b,i;
    16 }p[maxn],q[maxn];
    17 int N,NN,stk[maxn],sh;
    18 bool flag[maxn];
    19 
    20 inline bool cmp(Line a,Line b){
    21     return a.a==b.a?a.b>b.b:a.a<b.a;
    22 }
    23 
    24 inline double getx(Line a,Line b){
    25     return (double)(b.b-a.b)/(a.a-b.a);
    26 }
    27 inline bool nsame(int a,int b){
    28     return q[a].a!=q[b].a||q[a].b!=q[b].b;
    29 }
    30 
    31 int main(){
    32     int i,j,k;
    33     N=rd();for(i=1;i<=N;i++){
    34         p[i].a=rd(),p[i].b=rd();p[i].i=i;
    35     }
    36     sort(p+1,p+N+1,cmp);
    37     for(i=1,j=0;i<=N;i++){
    38         if(p[i].a==p[i-1].a&&p[i].b<p[i-1].b) continue;
    39         q[++j]=p[i];
    40     }NN=j;
    41     stk[sh=1]=1;
    42     for(i=2;i<=NN;i++){
    43         while(sh>=2&&nsame(stk[sh],i)&&(getx(q[i],q[stk[sh]])<=getx(q[stk[sh]],q[stk[sh-1]]))) sh--;
    44         stk[++sh]=i;
    45     }for(i=sh;i;i--) flag[q[stk[i]].i]=1;
    46     for(i=1;i<=N;i++) if(flag[i]) printf("%d ",i);
    47     return 0;
    48 }
  • 相关阅读:
    Python网络协议(osi七层协议)
    Python面向对象之反射,双下方法
    Python类的成员
    Python异常处理
    mysql 索引 慢查询优化 && 数据库性能优化
    数据库(视图、事务、存储过程、函数) && 数据库备份
    mysql数据库连接模块 pymysql && sql注入
    主线程与子线程的关系
    socket 编程实例 基于线程池实现服务端并发
    日常迷惑积累
  • 原文地址:https://www.cnblogs.com/Ressed/p/9634188.html
Copyright © 2011-2022 走看看