题意:
致力于建设全国示范和谐小村庄的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 }