• 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔


    1038: [ZJOI2008]瞭望塔

    Description

      致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。我们
    将H村抽象为一维的轮廓。如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描
    述H村的形状,这里x1 < x2 < …< xn。瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可
    以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长
    希望建造的塔高度尽可能小。请你写一个程序,帮助dadzhi村长计算塔的最小高度。

    Input

      第一行包含一个整数n,表示轮廓折线的节点数目。接下来第一行n个整数, 为x1 ~ xn. 第三行n个整数,为y1
     ~ yn。

    Output

      仅包含一个实数,为塔的最小高度,精确到小数点后三位。

    Sample Input

    【输入样例一】
    6
    1 2 4 5 6 7
    1 2 2 4 2 1
    【输入样例二】
    4
    10 20 49 59
    0 10 10 0

    Sample Output

    【输出样例一】
    1.000
    【输出样例二】
    14.500

    HINT

     N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。

    【分析】

      还没有AC就打题解真的好?【默默对拍中。。

      题目里面没有图,奉献一幅可爱的图?(这是样例1)

      

    绿色是山,紫色是可行域,红色的是最小的塔高。

     这题感觉吧跟多边形的核差不多,我们把轮廓线转换成半平面求角,然后考虑轮廓和半平面交的顶点(可以证明这里面一定存在最优塔高),

     从这个顶点垂直于x轴延伸求出塔高,然后计算最小值就好了。

    【1分钟后....

    终于AC了,啊啊啊范围弄小了。。。。。10^6不是范围【没有听PO姐话就傻逼了一下

    打半平面交的时候真是超级多错,最好弄eps搞精度。

    然后注意轮廓和半平面交的边界(求塔高的时候不要越界,会有问题的)

    就酱,真的是一周一题的缓慢速度。。。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<cmath>
      7 using namespace std;
      8 #define Maxn 310
      9 
     10 double INF=1e60;
     11 const double eps=0.000001;
     12 
     13 struct P {double x,y;};
     14 struct LN {P a,b;double slop;}l[Maxn],p[Maxn];
     15 
     16 double sx[Maxn],sy[Maxn];
     17 int n;
     18 
     19 P operator - (P x,P y)
     20 {
     21     P tt;
     22     tt.x=x.x-y.x;
     23     tt.y=x.y-y.y;
     24     return tt;
     25 }
     26 
     27 P operator + (P x,P y)
     28 {
     29     P tt;
     30     tt.x=x.x+y.x;
     31     tt.y=x.y+y.y;
     32     return tt;
     33 }
     34 
     35 P operator * (P x,double y)
     36 {
     37     P tt;
     38     tt.x=x.x*y;
     39     tt.y=x.y*y;
     40     return tt;
     41 }
     42 
     43 double Cross(P x,P y) {return x.x*y.y-x.y*y.x;}
     44 double Dot(P x,P y) {return x.x*y.x+x.y*y.y;}
     45 
     46 bool operator < (LN x,LN y) {return (x.slop==y.slop)?(Cross(x.b-x.a,y.b-x.a)<0):(x.slop<y.slop);}
     47 
     48 P inter(LN x,LN y)
     49 {
     50     P nw=y.a-x.a;
     51     double tt;
     52     P X=x.b-x.a,Y=y.b-y.a;
     53     tt=Cross(nw,X)/Cross(X,Y);
     54     return y.a+Y*tt;
     55 }
     56 
     57 bool jud(LN x,LN y,LN z)
     58 {
     59     P nw=inter(x,y);
     60     if(Cross(z.b-z.a,nw-z.a)<eps&&Cross(z.b-z.a,nw-z.a)>-eps) return 0;
     61     return Cross(z.b-z.a,nw-z.a)<0;
     62 }
     63 
     64 int cnt;
     65 void op()
     66 {
     67     for(int i=1;i<=cnt;i++)
     68     {
     69         printf("%.2lf %.2lf %.2lf %.2lf = %.2lf
    ",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y,l[i].slop);
     70     }printf("
    ");
     71 }
     72 
     73 void opp(int L,int R)
     74 {
     75     for(int i=L;i<=R;i++)
     76     {
     77         printf("%.2lf %.2lf %.2lf %.2lf = %.2lf
    ",p[i].a.x,p[i].a.y,p[i].b.x,p[i].b.y,p[i].slop);
     78     }printf("
    ");
     79 }
     80 
     81 P as[Maxn];
     82 int L,R;
     83 
     84 bool ffind()
     85 {
     86     for(int i=1;i<=n;i++) l[i].slop=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
     87     sort(l+1,l+1+n);
     88     
     89     cnt=1;
     90     for(int i=2;i<=n;i++)
     91     {
     92         if(l[i].slop!=l[cnt].slop) l[++cnt]=l[i];
     93     }
     94     // op();
     95     L=1,R=2;
     96     p[1]=l[1];p[2]=l[2];
     97         // opp(L,R);
     98     if(cnt<2) return 0;
     99     for(int i=3;i<=cnt;i++)
    100     {
    101         while(R>L&&jud(p[R],p[R-1],l[i])) R--;
    102         while(R>L&&jud(p[L],p[L+1],l[i])) L++;
    103         p[++R]=l[i];
    104         // opp(L,R);
    105     }
    106     if(R>L&&jud(p[R],p[R-1],p[L])) R--;
    107         // opp(L,R);
    108     if(R-L+1<2) return 0;
    109     return 1;
    110         // opp(L,R);
    111     /*double ans=INF;
    112     for(int i=L;i<R;i++)
    113     {
    114         P x=inter(p[i],p[i+1]);
    115         ans=ans<x.y?ans:x.y;
    116     }
    117     printf("%.3lf
    ",ans);*/
    118 }
    119 
    120 void get_ans()
    121 {
    122     double ans=INF;
    123     int ft=L;
    124     P fx=inter(p[L],p[L+1]);
    125     for(int i=1;i<=n+1;i++)
    126     {
    127         while(sx[i]>=fx.x&&ft<R)
    128         {
    129             ft++;
    130             fx=inter(p[ft],p[ft+1]);
    131         }
    132         LN nw;
    133         nw.a.x=sx[i];nw.a.y=sy[i];
    134         nw.b.x=sx[i];nw.b.y=sy[i]+1;
    135         P xx=inter(nw,p[ft]);
    136         ans=ans<xx.y-sy[i]?ans:xx.y-sy[i];
    137         // printf("==%.2lf
    ",xx.y-sy[i]);
    138     }
    139         // printf("--%.2lf
    ",ans);
    140     
    141     ft=1;
    142     LN now;
    143     now.a.x=sx[1];now.a.y=sy[1];
    144     now.b.x=sx[2];now.b.y=sy[2];
    145     for(int i=L;i<R;i++)
    146     {
    147         P x=inter(p[i],p[i+1]);
    148         if(x.x<sx[1]) continue;
    149         while(x.x>=sx[ft+1])
    150         {
    151             ft++;
    152             if(ft>n) break;
    153             // now.a.x=sx[ft];now.a.y=sy[ft];
    154             now.a=now.b;
    155             now.b.x=sx[ft+1];now.b.y=sy[ft+1];
    156         }
    157         if(ft>n) break;
    158         LN nw;
    159         nw.a=nw.b=x;nw.b.y=nw.b.y+1;
    160         P xx=inter(nw,now);
    161         ans=ans<x.y-xx.y?ans:x.y-xx.y;
    162         // printf("==%.2lf
    ",x.y-xx.y);
    163     }
    164     if(ans>=-eps&&ans<=eps) printf("0.000
    ");
    165     else printf("%.3lf
    ",ans);
    166 }
    167 
    168 int main()
    169 {
    170     scanf("%d",&n);
    171     for(int i=1;i<=n;i++) scanf("%lf",&sx[i]);
    172     for(int i=1;i<=n;i++) scanf("%lf",&sy[i]);
    173     n--;
    174     for(int i=1;i<=n;i++)
    175     {
    176         l[i].a.x=sx[i];l[i].a.y=sy[i];
    177         l[i].b.x=sx[i+1];l[i].b.y=sy[i+1];
    178     }
    179     if(!ffind()) printf("0.000
    ");
    180     else get_ans();
    181     return 0;
    182 }
    View Code

    做几何题真的就不删调试了。

    2016-12-29 17:09:28

  • 相关阅读:
    iOS-导航条
    iOS-存储
    iOS-模型传递
    iOS-日期相关
    iOS-UIViewController
    iOS-loadView方法
    iOS-UIWindow
    Spring 测试
    Spring条件注解@Conditional
    Spring多线程
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6233696.html
Copyright © 2020-2023  润新知