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

    题解:

    维护一个栈就好了,画画图就知道怎么维护了。。

    这两天总写不对计算几何的水题。。真是郁闷。。

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <algorithm>
      6 
      7 #define N 555555
      8 #define EPS 1e-7
      9 
     10 using namespace std;
     11 
     12 struct PO
     13 {
     14     double x,y;
     15     void prt() {printf("%lf       %lf\n",x,y);}
     16 }sk[N];
     17 
     18 struct LI
     19 {
     20     PO a,b;
     21     int id;
     22     double p,q;
     23     void prt() {printf("%lf     %lf     %lf     %lf\n",a.x,a.y,b.x,b.y);}
     24 }li[N],stk[N];
     25 
     26 int n,top,tp,bh[N];
     27 
     28 inline PO operator +(PO a,PO b)
     29 {
     30     a.x+=b.x; a.y+=b.y;
     31     return a;
     32 }
     33 
     34 inline PO operator -(PO a,PO b)
     35 {
     36     a.x-=b.x; a.y-=b.y;
     37     return a;
     38 }
     39 
     40 inline PO operator *(PO a,double k)
     41 {
     42     a.x*=k; a.y*=k;
     43     return a;
     44 }
     45 
     46 inline PO operator /(PO a,double k)
     47 {
     48     a.x/=k; a.y/=k;
     49     return a;
     50 }
     51 
     52 inline int dc(double x)
     53 {
     54     if(x>EPS) return 1;
     55     else if(x<-EPS) return -1;
     56     return 0;
     57 }
     58 
     59 inline void read()
     60 {
     61     scanf("%d",&n);
     62     double a,b;
     63     for(int i=1;i<=n;i++)
     64     {
     65         scanf("%lf%lf",&a,&b);
     66         li[i].a.x=0; li[i].a.y=b;
     67         if(dc(a)==0) li[i].b.x=29.3278,li[i].b.y=b;
     68         else li[i].b.x=29.3278,li[i].b.y=a*29.3278+b;
     69         li[i].p=a; li[i].q=b;
     70         li[i].id=i;
     71     }
     72 }
     73 
     74 inline double cross(const PO &a,const PO &b,const PO &c)
     75 {
     76     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
     77 }
     78 
     79 inline bool cmp(const LI &a,const LI &b)
     80 {
     81     if(dc(a.p-b.p)==0) return a.q>b.q;
     82     return a.p<b.p;
     83 }
     84 
     85 inline PO getpoint(const PO &a,const PO &b,const PO &c,const PO &d)
     86 {
     87     double k1=cross(a,d,c),k2=cross(b,c,d);
     88     PO tmp;tmp=b-a;
     89     return a+tmp*k1/(k1+k2);
     90 }
     91 
     92 inline void go()
     93 {
     94     PO c;
     95     sort(li+1,li+1+n,cmp);
     96     top=tp=0;
     97     for(int i=1;i<=n;i++)
     98     {
     99         if(dc(li[i].p-li[i-1].p)==0) continue;
    100         while(tp>=1)
    101         {
    102             c=getpoint(li[i].a,li[i].b,stk[top].a,stk[top].b);
    103             if(dc(c.x-sk[tp].x)<=0) top--,tp--;
    104             else break;
    105         }
    106         stk[++top]=li[i];
    107         if(top==2&&tp==0) sk[++tp]=getpoint(stk[top].a,stk[top].b,stk[top-1].a,stk[top-1].b);
    108         else if(tp>0) sk[++tp]=c;
    109     }
    110     for(int i=1;i<=top;i++) bh[i]=stk[i].id;
    111     sort(bh+1,bh+1+top);
    112     for(int i=1;i<top;i++) printf("%d ",bh[i]);
    113     printf("%d",bh[top]);
    114 }
    115 
    116 int main()
    117 {
    118     read(),go();
    119     return 0;
    120 }
  • 相关阅读:
    POJ 3904 Sky Code (容斥原理)
    HDU 4334 Trouble (暴力)
    UVA 10325 The Lottery( 容斥原理)
    HDU 2841 Visible Trees 数论+容斥原理
    UVA11806-Cheerleaders(容斥原理+二进制)
    HDU1695 GCD (欧拉函数+容斥原理)
    HDU 5651 xiaoxin juju needs help (组合数)
    最大子矩阵和 51Nod 1051 模板题
    最大子段和 模板题 51Nod 1049
    51Nod 1006 最长公共子序列Lcs问题 模板题
  • 原文地址:https://www.cnblogs.com/proverbs/p/2942068.html
Copyright © 2011-2022 走看看