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 }

 

posted @ 2017-03-02 07:27  ws_ccd  阅读(138)  评论(0编辑  收藏  举报