zoukankan      html  css  js  c++  java
  • 【BZOJ1007】【HNOI2008】水平可见直线

    依旧看黄学长代码,不过这回是看完后自己写的

    原题:

     在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条直线两两不重合.求出所有可见的直线.

    0 < N < 50000

    给线段求下凸包,还算比较简单把

    用栈,首先根据斜率排个序,这里建议如果斜率相等呢么y轴上截距递减,这样如果要插入的直线斜率和栈顶斜率相等直接停止就行了

    如果要插入的直线和栈中top-1的交点在栈中top和栈中top-2的交点的左边,呢么top--

    为什么呐

    手玩三条直线很容易看出来,图比较好画我就画一下吧(我也只能画简单的图了

    怎么计算交点呐

    因为是很简单的x=kx+b,这就是小学数学,为了增加文章的篇幅来扯一扯 _(:3 」∠)_

    就是解二元一次方程组,{y=k1x+b1,y=k2x+b2},下面减上面,(k2-k1)x=b1-b2,x=(b1-b2)/(k2-k1)

    然后随便搞一搞就行了,最后用bool记录答案来保证id递增

    小技巧:fabs是计算浮点数的绝对值,注意fabs计算的并不是差的绝对值,也就是说应该是fabs(a-b)而不是fabs(a,b),需要cmath

    我看黄学长和另一个人的代码比x的时候都是直接<=,算时x返回是double啊不是不能直接=么,然而还是过了,不知道为什么

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cmath>
     6 using namespace std;
     7 int read(){int z=0,mark=1;  char ch=getchar();
     8     while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
     9     while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
    10     return z*mark;
    11 }
    12 bool deng(double x,double y){  return fabs(x-y)<1e-8;}//fabs传的是绝对值,所以不能fabs(a-b)
    13 int n;  struct cdd{double k,b;  int id;}a[51000];//y=kx+b
    14 bool compare(cdd x,cdd y){  return (deng(x.k,y.k)) ? (x.b>y.b) : (x.k<y.k);}
    15 bool ans[51000];
    16 cdd zhan[51000];  int top=0;
    17 double get_x(cdd x,cdd y){  return (x.b-y.b)/(y.k-x.k);}
    18 void insert(cdd x){
    19     if(deng(x.k,zhan[top].k))  return ;
    20     while(top>1 && get_x(x,zhan[top-1]) <= get_x(zhan[top],zhan[top-1]))  top--;
    21     zhan[++top]=x;
    22 }
    23 int main(){//freopen("ddd.in","r",stdin);
    24     memset(ans,0,sizeof(ans));
    25     cin>>n;
    26     for(int i=1;i<=n;i++)  scanf("%lf%lf",&a[i].k,&a[i].b),a[i].id=i;
    27     sort(a+1,a+n+1,compare);
    28     a[0].k=a[0].b=-999999999;
    29     for(int i=1;i<=n;i++)  insert(a[i]);
    30     for(int i=1;i<=top;i++)  ans[zhan[i].id]=true;
    31     for(int i=1;i<=n;i++)if(ans[i])  printf("%d ",i);
    32     cout<<endl;
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    POJ 1659 Frogs' Neighborhood
    zoj 2913 Bus Pass(BFS)
    ZOJ 1008 Gnome Tetravex(DFS)
    POJ 1562 Oil Deposits (DFS)
    zoj 2165 Red and Black (DFs)poj 1979
    hdu 3954 Level up
    sgu 249 Matrix
    hdu 4417 Super Mario
    SPOJ (BNUOJ) LCM Sum
    hdu 2665 Kth number 划分树
  • 原文地址:https://www.cnblogs.com/JSL2018/p/5917130.html
Copyright © 2011-2022 走看看