http://poj.org/problem?id=2540
题意:给你每次行走的路径,而且告诉你每次离一个点光源是远了还是近了,要求每次光源可能存在的位置的面积。
思路:如果出现"same",说明光源在中垂线上,面积为0,否则我们考虑远了或者近了,实际上就是在路径中两点连成直线的中垂线就是半平面直线,近了在这条直线的远侧,远了在这条直线的近侧。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 const double Pi=acos(-1); 7 bool flag=0; 8 int tot; 9 struct Point{ 10 double x,y; 11 Point(){} 12 Point(double x0,double y0):x(x0),y(y0){} 13 }a[200005],p[200005]; 14 struct Line{ 15 Point s,e; 16 double slop; 17 Line(){} 18 Line(Point s0,Point e0):s(s0),e(e0){} 19 }l[200005],L[200005],c[200005]; 20 int read(){ 21 int t=0,f=1;char ch=getchar(); 22 while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} 23 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 24 return t*f; 25 } 26 double operator *(Point p1,Point p2){ 27 return p1.x*p2.y-p1.y*p2.x; 28 } 29 Point operator +(Point p1,Point p2){ 30 return Point(p1.x+p2.x,p1.y+p2.y); 31 } 32 Point operator -(Point p1,Point p2){ 33 return Point(p1.x-p2.x,p1.y-p2.y); 34 } 35 Point operator /(Point p1,double x){ 36 return Point(p1.x/x,p1.y/x); 37 } 38 bool cmp(Line p1,Line p2){ 39 if (p1.slop!=p2.slop) return p1.slop<p2.slop; 40 else return (p1.e-p1.s)*(p2.e-p1.s)<=0; 41 } 42 Point turn(Point p1,double ang){ 43 double Cos=cos(ang),Sin=sin(ang); 44 double x=p1.x*Cos-p1.y*Sin; 45 double y=p1.x*Sin+p1.y*Cos; 46 return Point(x,y); 47 } 48 Point inter(Line p1,Line p2){ 49 double t1=(p2.e-p1.s)*(p1.e-p1.s); 50 double t2=(p1.e-p1.s)*(p2.s-p1.s); 51 double k=(t2)/(t1+t2); 52 double x=(p2.e.x-p2.s.x)*k+p2.s.x; 53 double y=(p2.e.y-p2.s.y)*k+p2.s.y; 54 return Point(x,y); 55 } 56 bool jud(Line p1,Line p2,Line p3){ 57 Point p=inter(p1,p2); 58 return (p-p3.s)*(p3.e-p3.s)>0; 59 } 60 double query(){ 61 std::sort(l+1,l+1+tot,cmp); 62 if (!cmp(l[tot-1],l[tot])) return 0.0; 63 int cnt=1;L[1]=l[1]; 64 for (int i=2;i<=tot;i++) 65 if (l[i].slop!=l[i-1].slop) L[++cnt]=l[i]; 66 int ll=1,rr=2;c[ll]=L[1];c[rr]=L[2]; 67 for (int i=3;i<=cnt;i++){ 68 while (ll<rr&&jud(c[rr],c[rr-1],L[i])) rr--; 69 while (ll<rr&&jud(c[ll],c[ll+1],L[i])) ll++; 70 c[++rr]=L[i]; 71 } 72 while (ll<rr&&jud(c[rr],c[rr-1],c[ll])) rr--; 73 while (ll<rr&&jud(c[ll],c[ll+1],c[rr])) ll++; 74 if (rr-ll+1<3) {flag=1;return 0.00;} 75 double ans=0; 76 cnt=0; 77 c[rr+1]=c[ll]; 78 for (int i=ll;i<=rr;i++) 79 a[++cnt]=inter(c[i],c[i+1]); 80 a[cnt+1]=a[1]; 81 for (int i=1;i<=cnt;i++) 82 ans+=a[i]*a[i+1]; 83 ans/=2.0; 84 return fabs(ans); 85 } 86 int main(){ 87 p[0]=Point(0,0); 88 char s[200005];double x,y;flag=0;int i=1; 89 l[++tot].s=Point(0,10);l[tot].e=Point(0,0);l[tot].slop=atan2(l[tot].e.y-l[tot].s.y,l[tot].e.x-l[tot].s.x); 90 l[++tot].s=Point(0,0);l[tot].e=Point(10,0);l[tot].slop=atan2(l[tot].e.y-l[tot].s.y,l[tot].e.x-l[tot].s.x); 91 l[++tot].s=Point(10,0);l[tot].e=Point(10,10);l[tot].slop=atan2(l[tot].e.y-l[tot].s.y,l[tot].e.x-l[tot].s.x); 92 l[++tot].s=Point(10,10);l[tot].e=Point(0,10);l[tot].slop=atan2(l[tot].e.y-l[tot].s.y,l[tot].e.x-l[tot].s.x); 93 while (scanf("%lf%lf",&p[i].x,&p[i].y)!=EOF){ 94 scanf("%s",s+1); 95 if (s[1]=='S') flag=1; 96 if (flag){puts("0.00");continue;} 97 if (s[1]=='C'){ 98 Point mid=(p[i]+p[i-1])/2.0; 99 l[++tot].e=mid+turn(p[i]-p[i-1],Pi/2.0); 100 l[tot].s=mid; 101 }else{ 102 Point mid=(p[i]+p[i-1])/2.0; 103 l[++tot].e=mid+turn(p[i]-p[i-1],Pi*3.0/2.0); 104 l[tot].s=mid; 105 } 106 l[tot].slop=atan2(l[tot].e.y-l[tot].s.y,l[tot].e.x-l[tot].s.x); 107 printf("%.2f ",query()); 108 i++; 109 } 110 }