• zjoi 2008 tower 瞭望塔 半平面交


    题意:

      致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。我们将H村抽象为一维的轮廓。如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描述H村的形状,这里x1 < x2 < …< xn。瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长希望建造的塔高度尽可能小。请你写一个程序,帮助dadzhi村长计算塔的最小高度。
     
    思路:半平面交
     
      1 #include<iostream>
    2 #include<cstdio>
    3 #include<cmath>
    4 #include<cstdio>
    5 #include<vector>
    6 using namespace std;
    7 #define MAXN 310
    8 #define EPS 1e-8
    9 int n;
    10 const double INF=1e10;
    11 struct point
    12 {
    13 double x,y;
    14 bool mark;
    15 point() {}
    16 point(double x0,double y0): x(x0),y(y0),mark(1) {}
    17 };
    18 point a[MAXN];
    19 vector<point> p;
    20 point operator -(const point &A,const point &B)
    21 {
    22 return point(A.x-B.x,A.y-B.y);
    23 }
    24 double cross(point p1,point p2)
    25 {
    26 return p1.x*p2.y-p1.y*p2.x;
    27 }
    28 int dblcmp(double x)
    29 {
    30 if(fabs(x)<EPS) return 0;
    31 return x>0? 1:-1;
    32 }
    33 point find_intersection(point p1,point p2,point p3,point p4)
    34 {
    35 double s1=fabs(cross(p1-p3,p1-p2));
    36 double s2=fabs(cross(p1-p4,p1-p2));
    37 return point((p3.x*s2+p4.x*s1)/(s1+s2),(p3.y*s2+p4.y*s1)/(s1+s2));
    38 }
    39 void update(double k,double b)
    40 {
    41 int i;
    42 point temp;
    43 for(i=0;i<p.size();i++)
    44 {
    45 if(dblcmp(p[i].y-p[i].x*k-b)>=0) p[i].mark=1;
    46 else p[i].mark=0;
    47 }
    48 p.push_back(p[0]);
    49 for(i=0;i<p.size()-1;i++)
    50 {
    51 if(p[i].mark^p[i+1].mark==1)
    52 {
    53 temp=find_intersection(point(0,b),point(1,k+b),p[i],p[i+1]);
    54 p.insert(p.begin()+i+1,temp);
    55 i++;
    56 }
    57 }
    58 p.pop_back();
    59 for(i=0;i<p.size();i++)
    60 if(p[i].mark==0)
    61 p.erase(p.begin()+i), i--;
    62 }
    63 void make()
    64 {
    65 int i;
    66 double k,b;
    67 for(i=1;i<n;i++)
    68 {
    69 k=(a[i+1].y-a[i].y)/(a[i+1].x-a[i].x);
    70 b=a[i].y-a[i].x*k;
    71 update(k,b);
    72 }
    73 }
    74 void solve()
    75 {
    76 double ans=INF,temp;
    77 int i,j;
    78 for(i=0;i<p.size();i++)
    79 {
    80 for(j=1;j<n;j++)
    81 if(dblcmp(p[i].x-a[j].x)>=0&&dblcmp(a[j+1].x-p[i].x)>=0) break;
    82 temp=(p[i].x-a[j].x)/(a[j+1].x-a[j].x)*(a[j+1].y-a[j].y)+a[j].y;
    83 if(p[i].y-temp<ans) ans=p[i].y-temp;
    84 }
    85 p.push_back(p[0]);
    86 for(i=1;i<=n;i++)
    87 {
    88 for(j=0;j<p.size()-1;j++)
    89 if(dblcmp(a[i].x-p[j].x)*dblcmp(p[j+1].x-a[i].x)>=0)
    90 {
    91 temp=(a[i].x-p[j].x)/(p[j+1].x-p[j].x)*(p[j+1].y-p[j].y)+p[j].y;
    92 if(temp-a[i].y<ans) ans=temp-a[i].y;
    93 }
    94 }
    95 printf("%.3lf\n",ans);
    96 }
    97 int main()
    98 {
    99 freopen("tower.in","r",stdin);
    100 freopen("tower.out","w",stdout);
    101 scanf("%d",&n);
    102 int i;
    103 for(i=1;i<=n;i++) scanf("%lf",&a[i].x);
    104 for(i=1;i<=n;i++) scanf("%lf",&a[i].y);
    105 p.push_back(point(a[1].x,-INF));
    106 p.push_back(point(a[n].x,-INF));
    107 p.push_back(point(a[n].x,INF));
    108 p.push_back(point(a[1].x,INF));
    109 make();
    110 /*cout<<p.size()<<endl;
    111 for(i=0;i<p.size();i++)
    112 cout<<p[i].x<<" "<<p[i].y<<endl;*/
    113 solve();
    114 return 0;
    115 }

     
  • 相关阅读:
    最短路径覆盖问题
    js 程序执行与顺序实现详解
    ajax中的application/x-www-form-urlencoded中的使用[转]
    javascript跨浏览器操作xml
    javascript 正则表达式
    JavaScript面向对象编程(2)-- 类的定义
    JavaScript面向对象编程(1)-- 基础
    constructor、prototype、isPrototypeOf、instanceof、in 、hasOwnProperty
    valueOf()对象返回值
    javascript中的toString()、toLocaleString()方法
  • 原文地址:https://www.cnblogs.com/myoi/p/2437460.html
Copyright © 2020-2023  润新知