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 }