POJ 2540 Hotter Colder

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 }
原文地址:https://www.cnblogs.com/qzqzgfy/p/5654450.html