zoukankan      html  css  js  c++  java
  • bzoj 1007 水平可见直线

    题目大意:

    有一些直线若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为可见的,否则Li为被覆盖的

    思路:

    可以看出来最后图形应该为一个下凸包

    对于下凸包上的每个点,斜率都应该递增,而且横坐标递增

    因此我们先对每条线的斜率进行排序

    然后使用单调栈维护即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<set>
     8 #include<map>
     9 #include<vector>
    10 #include<stack>
    11 #include<queue>
    12 #define ll long long
    13 #define inf 2147383611
    14 #define MAXN 50100
    15 using namespace std;
    16 inline ll read()
    17 {
    18     ll x=0,f=1;
    19     char ch;ch=getchar();
    20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    21     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    22     return x*f;
    23 }
    24 struct sline
    25 {
    26     double k,b;
    27     int num;
    28 }l[MAXN],st[MAXN];
    29 const double eps=1e-8;
    30 bool cmp1(sline A,sline B) {return A.k<B.k||(fabs(A.k-B.k)<eps&&A.b<B.b);}
    31 bool cmp2(sline A,sline B) {return A.num<B.num;}
    32 double insct(sline A,sline B)
    33 {
    34     return (B.b-A.b)/(A.k-B.k);
    35 }
    36 int n,top;
    37 int main()
    38 {
    39     n=read();
    40     for(int i=1;i<=n;i++) {scanf("%lf%lf",&l[i].k,&l[i].b);l[i].num=i;}
    41     sort(l+1,l+n+1,cmp1);
    42     for(int i=1;i<=n;i++)
    43     {
    44         while(fabs(st[top].k-l[i].k)<eps&&top) top--;
    45         while(insct(st[top],st[top-1])>=insct(l[i],st[top-1])&&top>1) top--;
    46         st[++top]=l[i];
    47     }
    48     sort(st+1,st+top+1,cmp2);
    49     for(int i=1;i<=top;i++) printf("%d ",st[i].num);
    50 }
    View Code
  • 相关阅读:
    debug和console.write()有什么区别
    数据源绑定DataGridViewComboBox
    关于SqlDataAdapter的Update()方法
    反思。。
    C语言光标移动
    关于湖南工业大学“蓝桥杯”预选赛
    Left digit
    突然想写个超级马里奥
    如何知道一个数有多大位数
    Hut 新生训练赛第二场 迟来的解题报告
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7718394.html
Copyright © 2011-2022 走看看