zoukankan      html  css  js  c++  java
  • bzoj 1038: [ZJOI2008]瞭望塔

    题意大概就是在村子(山)轮廓之上建一个多么高的塔,可以看到村子全部的点。(一开始怎么也看不懂题意2333)

    显然,相邻两点连线,然后所有线交出的区域就是塔建造的可行范围,所以就可以半平面交了233。

    答案最小,,,就在分段函数的分段端点处取???(雾,画个图能看出来)

    如此神的题%%hzwer

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #define eps 1e-8
     5 using namespace std;
     6 double ans=1e60;
     7 int n,cnt,top,tot;
     8 struct point{double x,y;}p[1005],a[1005];
     9 struct line{point a,b; double angle;} l[1005],q[1005];
    10 point operator - (point a, point b){
    11     point t; t.x=a.x-b.x; t.y=a.y-b.y; return t;
    12 }
    13 double operator * (point a, point b){
    14     return a.x*b.y-a.y*b.x;
    15 }
    16 bool operator < (line a, line b){
    17     if (a.angle==b.angle) return (a.b-a.a)*(b.b-a.a)>0;
    18     return a.angle<b.angle;
    19 }
    20 point intersection(line a, line b)
    21 {
    22     double k1,k2,t;
    23     k1=(b.b-a.a)*(a.b-a.a);
    24     k2=(a.b-a.a)*(b.a-a.a);
    25     t=k1/(k1+k2);
    26     point ans;
    27     ans.x=b.b.x+(b.a.x-b.b.x)*t;
    28     ans.y=b.b.y+(b.a.y-b.b.y)*t;
    29     return ans;
    30 }
    31 bool jud(line a, line b, line t)
    32 {
    33     point p=intersection(a,b);
    34     return (t.b-t.a)*(p-t.a)<0;
    35 }
    36 void half_plane_intersection()
    37 {
    38     int L=1,R=0; tot=0;
    39     for (int i=1; i<=cnt; i++)
    40     {
    41         if (l[i].angle!=l[i-1].angle) tot++;
    42         l[tot]=l[i];
    43     }
    44     cnt=tot;
    45     q[++R]=l[1]; q[++R]=l[2];
    46     for (int i=3; i<=cnt; i++)
    47     {
    48         while (L<R && jud(q[R-1],q[R],l[i])) R--;
    49         while (L<R && jud(q[L+1],q[L],l[i])) L++;
    50         q[++R]=l[i]; 
    51     }
    52     while (L<R && jud(q[R-1],q[R],q[L])) R--;
    53     while (L<R && jud(q[L+1],q[L],q[R])) L++;
    54     tot=0;
    55     for (int i=L; i<R; i++)
    56         a[++tot]=intersection(q[i],q[i+1]);
    57 }
    58 void pre()
    59 {
    60     p[0].x=p[1].x; p[0].y=100001;
    61     p[n+1].x=p[n].x; p[n+1].y=100001;
    62     for (int i=1; i<=n; i++)
    63     {
    64         l[++cnt].a=p[i-1]; l[cnt].b=p[i];
    65         l[++cnt].a=p[i]; l[cnt].b=p[i+1];
    66     }
    67     for (int i=1; i<=cnt; i++)
    68         l[i].angle=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
    69     sort(l+1,l+cnt+1);
    70 }
    71 void get_ans()
    72 {
    73     for (int k=1; k<=tot; k++)
    74         for (int i=1; i<n; i++)
    75         {
    76             point t; t.x=a[k].x; t.y=-1;
    77             if (a[k].x>=p[i].x && a[k].x<=p[i+1].x)
    78                 ans=min(ans,a[k].y-intersection((line){p[i],p[i+1]},(line){t,a[k]}).y);
    79         }
    80     for (int k=1; k<=n; k++)
    81         for (int i=1; i<tot; i++)
    82         {
    83             point t; t.x=p[k].x; t.y=-1;
    84             if (p[k].x>=a[i].x && p[k].x<=a[i+1].x)
    85                 ans=min(ans,intersection((line){a[i],a[i+1]},(line){t,p[k]}).y-p[k].y);
    86         }
    87         
    88 }
    89 int main()
    90 {
    91     scanf("%d",&n);
    92     for (int i=1; i<=n; i++) scanf("%lf",&p[i].x);
    93     for (int i=1; i<=n; i++) scanf("%lf",&p[i].y);
    94     pre();
    95     half_plane_intersection();
    96     get_ans();
    97     printf("%.3lf",ans);
    98     return 0;
    99 }
  • 相关阅读:
    函数嵌套,层级嵌套函数就是闭包,包就是一层的意思,闭就是封装的意思封装的变量
    高阶函数
    装饰器=高阶函数+函数嵌套+闭包
    生产者和消费者模型
    【HDOJ】Power Stations
    【HDOJ】5046 Airport
    【HDOJ】3957 Street Fighter
    【HDOJ】2295 Radar
    【HDOJ】3909 Sudoku
    【POJ】3076 Sudoku
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6488643.html
Copyright © 2011-2022 走看看