bzoj 2451 Uyuw's Concert
裸的半平面交。感觉这些东西,纯属在考代码能力啊。。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #define eps 1e-8 5 using namespace std; 6 int n,tot; 7 double ans; 8 struct point{double x,y;}a[20005]; 9 struct line{point a,b; double angle;}l[20005],q[20005]; 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 long 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 (b.b-a.a)*(b.a-a.a)<0; 18 return a.angle<b.angle; 19 } 20 point intersection_point(line a, line b) 21 { 22 double k1,k2,t; 23 point ans; 24 k1=(a.b-b.a)*(b.b-b.a); 25 k2=(b.b-b.a)*(a.a-b.a); 26 t=k1/(k1+k2); 27 ans.x=a.b.x+(a.a.x-a.b.x)*t; 28 ans.y=a.b.y+(a.a.y-a.b.y)*t; 29 return ans; 30 } 31 bool judge(line a, line b, line t) 32 { 33 point p=intersection_point(a,b); 34 // printf("%lf %lf\n",a.b.x,a.b.y); 35 return (t.a-p)*(t.b-p)<0; 36 } 37 void half_plane_intersection() 38 { 39 sort(l+1,l+n+1); 40 int top=1,bottom=0; tot=0; 41 for (int i=1; i<=n; i++) 42 if (l[i].angle!=l[i-1].angle) l[++tot]=l[i]; 43 n=tot; q[0]=l[1]; q[1]=l[2]; 44 //for (int i=1; i<=n; i++) 45 // printf("%.1lf %.1lf %.1lf %.1lf\n",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y); 46 for (int i=3; i<=n; i++) 47 { 48 while (bottom<top && judge(q[top],q[top-1],l[i])) top--; 49 while (bottom<top && judge(q[bottom],q[bottom+1],l[i])) bottom++; 50 q[++top]=l[i]; 51 } 52 while (bottom<top && judge(q[top],q[top-1],q[bottom])) top--; 53 while (bottom<top && judge(q[bottom],q[bottom+1],q[top])) bottom++; 54 q[top+1]=q[bottom]; 55 tot=0; 56 for (int i=bottom; i<=top; i++) 57 a[++tot]=intersection_point(q[i],q[i+1]); 58 } 59 void get_area() 60 { 61 if (tot<3) return; 62 a[++tot]=a[1]; 63 //for (int i=1; i<=tot; i++) 64 // printf("%lf %lf\n",a[i].x,a[i].y); while (1); 65 for (int i=1; i<=tot; i++) 66 ans+=a[i]*a[i+1]; 67 ans=fabs(ans)/2; 68 } 69 int main() 70 { 71 while (~scanf("%d",&n)) 72 { 73 for (int i=1; i<=n; i++) 74 scanf("%lf%lf%lf%lf",&l[i].a.x,&l[i].a.y,&l[i].b.x,&l[i].b.y); 75 l[++n].a.x=0; l[n].a.y=0; l[n].b.x=10000; l[n].b.y=0; 76 l[++n].a.x=10000; l[n].a.y=0; l[n].b.x=10000; l[n].b.y=10000; 77 l[++n].a.x=10000; l[n].a.y=10000; l[n].b.x=0; l[n].b.y=10000; 78 l[++n].a.x=0; l[n].a.y=10000; l[n].b.x=0; l[n].b.y=0; 79 for (int i=1; i<=n; i++) 80 l[i].angle=atan2((l[i].b.y-l[i].a.y),(l[i].b.x-l[i].a.x)); 81 half_plane_intersection(); 82 ans=0; get_area(); 83 printf("%.1lf",ans); 84 } 85 return 0; 86 }