zoukankan      html  css  js  c++  java
  • hdu3982 直线切多边形 【WA中...】

    题意:有一块蛋糕,上面有一颗cherry。用刀子切n次,求切完之后有cherry的那部分的面积

    My solution:

    先做一个大矩形,使cake内切于这个大矩形。如图:

    然后不断切这个大矩形,每次切割的时候保留与cherry同侧的那部分。最后剩下的就是一个多边形。求该多边形与圆的面积交即可。

    在切割的时候如何保证留下来的是与cherry同侧的部分呢?很简单

    方法不难,但是一直WA= =。遇到了个奇怪的问题:

    对于这组数据:

    3

    5 2
    -5 0 5 3
    -5 0 5 -3
    0 0
    5 2
    -5 0 5 3
    -5 0 5 -3
    0 4.9
    5 2
    -5 0 5 3
    -5 0 5 -3
    0 -4.9

    画出来图是这样的:

    标程输出结果:

    My solution:

    可是标程明显不对啊尼玛!加起来都超过1了是什么鬼!

    思考ing.........

    附WA code:

       1 #include<vector>
       2 #include<list>
       3 #include<map>
       4 #include<set>
       5 #include<deque>
       6 #include<queue>
       7 #include<stack>
       8 #include<bitset>
       9 #include<algorithm>
      10 #include<functional>
      11 #include<numeric>
      12 #include<utility>
      13 #include<iostream>
      14 #include<sstream>
      15 #include<iomanip>
      16 #include<cstdio>
      17 #include<cmath>
      18 #include<cstdlib>
      19 #include<cctype>
      20 #include<string>
      21 #include<cstring>
      22 #include<cstdio>
      23 #include<cmath>
      24 #include<cstdlib>
      25 #include<ctime>
      26 #include<climits>
      27 #include<complex>
      28 #define mp make_pair
      29 #define pb push_back
      30 using namespace std;
      31 const double eps=1e-6;
      32 const double pi=acos(-1.0);
      33 const double inf=1e20;
      34 const int maxp=11000;
      35 
      36 int sgn(double x)
      37 {
      38     if (fabs(x)<eps)    return 0;
      39     if (x<0)    return -1;
      40         else return 1;
      41 }
      42 
      43 int dblcmp(double d)
      44 {
      45     if (fabs(d)<eps)return 0;
      46     return d>eps?1:-1;
      47 }
      48 
      49 inline double sqr(double x){return x*x;}
      50 
      51 struct point
      52 {
      53     double x,y;
      54     point(){}
      55     point(double _x,double _y):
      56     x(_x),y(_y){};
      57     void input()
      58     {
      59         scanf("%lf%lf",&x,&y);
      60     }
      61     void output()
      62     {
      63         printf("%.2f %.2f
    ",x,y);
      64     }
      65     bool operator==(point a)const
      66     {
      67         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
      68     }
      69     bool operator<(point a)const
      70     {
      71         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
      72     }
      73 
      74     point operator +(const point &b)const
      75     {
      76         return point(x+b.x,y+b.y);
      77     }
      78     point operator -(const point &b)const
      79     {
      80         return point(x-b.x,y-b.y);
      81     }
      82     point operator *(const double &k)const
      83     {
      84         return point(x*k,y*k);
      85     }
      86     point operator /(const double &k)const
      87     {
      88         return point(x/k,y/k);
      89     }
      90     double operator *(const point &b)const
      91     {
      92         return x*b.x+y*b.y;
      93     }
      94     double operator ^(const point &b)const
      95     {
      96         return x*b.y-y*b.x;
      97     }
      98 
      99     double len()
     100     {
     101         return hypot(x,y);
     102     }
     103     double len2()
     104     {
     105         return x*x+y*y;
     106     }
     107     double distance(point p)
     108     {
     109         return hypot(x-p.x,y-p.y);
     110     }
     111     point add(point p)
     112     {
     113         return point(x+p.x,y+p.y);
     114     }
     115     point sub(point p)
     116     {
     117         return point(x-p.x,y-p.y);
     118     }
     119     point mul(double b)
     120     {
     121         return point(x*b,y*b);
     122     }
     123     point div(double b)
     124     {
     125         return point(x/b,y/b);
     126     }
     127     double dot(point p)
     128     {
     129         return x*p.x+y*p.y;
     130     }
     131     double det(point p)
     132     {
     133         return x*p.y-y*p.x;
     134     }
     135     double rad(point a,point b)
     136     {
     137         point p=*this;
     138         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
     139     }
     140     point trunc(double r)
     141     {
     142         double l=len();
     143         if (!dblcmp(l))return *this;
     144         r/=l;
     145         return point(x*r,y*r);
     146     }
     147     point rotleft()
     148     {
     149         return point(-y,x);
     150     }
     151     point rotright()
     152     {
     153         return point(y,-x);
     154     }
     155     point rotate(point p,double angle)//绕点p逆时针旋转angle角度
     156     {
     157         point v=this->sub(p);
     158         double c=cos(angle),s=sin(angle);
     159         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
     160     }
     161 };
     162 
     163 struct line
     164 {
     165     point a,b;
     166     line(){}
     167     line(point _a,point _b)
     168     {
     169         a=_a;
     170         b=_b;
     171     }
     172     bool operator==(line v)
     173     {
     174         return (a==v.a)&&(b==v.b);
     175     }
     176     //倾斜角angle
     177     line(point p,double angle)
     178     {
     179         a=p;
     180         if (dblcmp(angle-pi/2)==0)
     181         {
     182             b=a.add(point(0,1));
     183         }
     184         else
     185         {
     186             b=a.add(point(1,tan(angle)));
     187         }
     188     }
     189     //ax+by+c=0
     190     line(double _a,double _b,double _c)
     191     {
     192         if (dblcmp(_a)==0)
     193         {
     194             a=point(0,-_c/_b);
     195             b=point(1,-_c/_b);
     196         }
     197         else if (dblcmp(_b)==0)
     198         {
     199             a=point(-_c/_a,0);
     200             b=point(-_c/_a,1);
     201         }
     202         else
     203         {
     204             a=point(0,-_c/_b);
     205             b=point(1,(-_c-_a)/_b);
     206         }
     207     }
     208     void input()
     209     {
     210         a.input();
     211         b.input();
     212     }
     213     void adjust()
     214     {
     215         if (b<a)swap(a,b);
     216     }
     217     double length()
     218     {
     219         return a.distance(b);
     220     }
     221     double angle()//直线倾斜角 0<=angle<180
     222     {
     223         double k=atan2(b.y-a.y,b.x-a.x);
     224         if (dblcmp(k)<0)k+=pi;
     225         if (dblcmp(k-pi)==0)k-=pi;
     226         return k;
     227     }
     228     //点和线段关系
     229     //1 在逆时针
     230     //2 在顺时针
     231     //3 平行
     232     int relation(point p)
     233     {
     234         int c=dblcmp(p.sub(a).det(b.sub(a)));
     235         if (c<0)return 1;
     236         if (c>0)return 2;
     237         return 3;
     238     }
     239     bool pointonseg(point p)
     240     {
     241         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
     242     }
     243     bool parallel(line v)
     244     {
     245         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
     246     }
     247     //2 规范相交
     248     //1 非规范相交
     249     //0 不相交
     250     int segcrossseg(line v)
     251     {
     252         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
     253         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
     254         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
     255         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
     256         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
     257         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
     258                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
     259                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
     260                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
     261     }
     262     int linecrossseg(line v)//*this seg v line
     263     {
     264         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
     265         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
     266         if ((d1^d2)==-2)return 2;
     267         return (d1==0||d2==0);
     268     }
     269     //0 平行
     270     //1 重合
     271     //2 相交
     272     int linecrossline(line v)
     273     {
     274         if ((*this).parallel(v))
     275         {
     276             return v.relation(a)==3;
     277         }
     278         return 2;
     279     }
     280     point crosspoint(line v)
     281     {
     282         double a1=v.b.sub(v.a).det(a.sub(v.a));
     283         double a2=v.b.sub(v.a).det(b.sub(v.a));
     284         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
     285     }
     286     double dispointtoline(point p)
     287     {
     288         return fabs(p.sub(a).det(b.sub(a)))/length();
     289     }
     290     double dispointtoseg(point p)
     291     {
     292         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
     293         {
     294             return min(p.distance(a),p.distance(b));
     295         }
     296         return dispointtoline(p);
     297     }
     298     point lineprog(point p)
     299     {
     300         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
     301     }
     302     point symmetrypoint(point p)
     303     {
     304         point q=lineprog(p);
     305         return point(2*q.x-p.x,2*q.y-p.y);
     306     }
     307 };
     308 
     309 struct Vector:public point
     310 {
     311     Vector(){}
     312     Vector(double a,double b)
     313     {
     314         x=a;    y=b;
     315     }
     316     Vector(point _a,point _b)   //a->b
     317     {
     318         double dx=_b.x-_a.x;
     319         double dy=_b.y-_a.y;
     320         x=dx;   y=dy;
     321     }
     322     Vector(line v)
     323     {
     324         double dx=v.b.x-v.a.x;
     325         double dy=v.b.y-v.a.y;
     326         x=dx;   y=dy;
     327     }
     328     double length()
     329     {
     330         return (sqrt(x*x+y*y));
     331     }
     332     Vector Normal()
     333     {
     334         double L=sqrt(x*x+y*y);
     335         Vector Vans=Vector(-y/L,x/L);
     336         return Vans;
     337     }
     338 };
     339 
     340 struct circle
     341 {
     342     point p;
     343     double r;
     344     circle(){}
     345     circle(point _p,double _r):
     346     p(_p),r(_r){};
     347     circle(double x,double y,double _r):
     348     p(point(x,y)),r(_r){};
     349     circle(point a,point b,point c)//三角形的外接圆
     350     {
     351         p=line(a.add(b).div(2),a.add(b).div(2).add(b.sub(a).rotleft())).crosspoint(line(c.add(b).div(2),c.add(b).div(2).add(b.sub(c).rotleft())));
     352         r=p.distance(a);
     353     }
     354     circle(point a,point b,point c,bool t)//三角形的内切圆
     355     {
     356         line u,v;
     357         double m=atan2(b.y-a.y,b.x-a.x),n=atan2(c.y-a.y,c.x-a.x);
     358         u.a=a;
     359         u.b=u.a.add(point(cos((n+m)/2),sin((n+m)/2)));
     360         v.a=b;
     361         m=atan2(a.y-b.y,a.x-b.x),n=atan2(c.y-b.y,c.x-b.x);
     362         v.b=v.a.add(point(cos((n+m)/2),sin((n+m)/2)));
     363         p=u.crosspoint(v);
     364         r=line(a,b).dispointtoseg(p);
     365     }
     366     void input()
     367     {
     368         p.input();
     369         scanf("%lf",&r);
     370     }
     371     void output()
     372     {
     373         printf("%.2lf %.2lf %.2lf
    ",p.x,p.y,r);
     374     }
     375     bool operator==(circle v)
     376     {
     377         return ((p==v.p)&&dblcmp(r-v.r)==0);
     378     }
     379     bool operator<(circle v)const
     380     {
     381         return ((p<v.p)||(p==v.p)&&dblcmp(r-v.r)<0);
     382     }
     383     double area()
     384     {
     385         return pi*sqr(r);
     386     }
     387     double circumference()
     388     {
     389         return 2*pi*r;
     390     }
     391     //0 圆外
     392     //1 圆上
     393     //2 圆内
     394     int relation(point b)
     395     {
     396         double dst=b.distance(p);
     397         if (dblcmp(dst-r)<0)return 2;
     398         if (dblcmp(dst-r)==0)return 1;
     399         return 0;
     400     }
     401     int relationseg(line v)
     402     {
     403         double dst=v.dispointtoseg(p);
     404         if (dblcmp(dst-r)<0)return 2;
     405         if (dblcmp(dst-r)==0)return 1;
     406         return 0;
     407     }
     408     int relationline(line v)
     409     {
     410         double dst=v.dispointtoline(p);
     411         if (dblcmp(dst-r)<0)return 2;
     412         if (dblcmp(dst-r)==0)return 1;
     413         return 0;
     414     }
     415     //过a b两点 半径r的两个圆
     416     int getcircle(point a,point b,double r,circle&c1,circle&c2)
     417     {
     418         circle x(a,r),y(b,r);
     419         int t=x.pointcrosscircle(y,c1.p,c2.p);
     420         if (!t)return 0;
     421         c1.r=c2.r=r;
     422         return t;
     423     }
     424     //与直线u相切 过点q 半径r1的圆
     425     int getcircle(line u,point q,double r1,circle &c1,circle &c2)
     426     {
     427         double dis=u.dispointtoline(q);
     428         if (dblcmp(dis-r1*2)>0)return 0;
     429         if (dblcmp(dis)==0)
     430         {
     431             c1.p=q.add(u.b.sub(u.a).rotleft().trunc(r1));
     432             c2.p=q.add(u.b.sub(u.a).rotright().trunc(r1));
     433             c1.r=c2.r=r1;
     434             return 2;
     435         }
     436         line u1=line(u.a.add(u.b.sub(u.a).rotleft().trunc(r1)),u.b.add(u.b.sub(u.a).rotleft().trunc(r1)));
     437         line u2=line(u.a.add(u.b.sub(u.a).rotright().trunc(r1)),u.b.add(u.b.sub(u.a).rotright().trunc(r1)));
     438         circle cc=circle(q,r1);
     439         point p1,p2;
     440         if (!cc.pointcrossline(u1,p1,p2))cc.pointcrossline(u2,p1,p2);
     441         c1=circle(p1,r1);
     442         if (p1==p2)
     443         {
     444             c2=c1;return 1;
     445         }
     446         c2=circle(p2,r1);
     447         return 2;
     448     }
     449     //同时与直线u,v相切 半径r1的圆
     450     int getcircle(line u,line v,double r1,circle &c1,circle &c2,circle &c3,circle &c4)
     451     {
     452         if (u.parallel(v))return 0;
     453         line u1=line(u.a.add(u.b.sub(u.a).rotleft().trunc(r1)),u.b.add(u.b.sub(u.a).rotleft().trunc(r1)));
     454         line u2=line(u.a.add(u.b.sub(u.a).rotright().trunc(r1)),u.b.add(u.b.sub(u.a).rotright().trunc(r1)));
     455         line v1=line(v.a.add(v.b.sub(v.a).rotleft().trunc(r1)),v.b.add(v.b.sub(v.a).rotleft().trunc(r1)));
     456         line v2=line(v.a.add(v.b.sub(v.a).rotright().trunc(r1)),v.b.add(v.b.sub(v.a).rotright().trunc(r1)));
     457         c1.r=c2.r=c3.r=c4.r=r1;
     458         c1.p=u1.crosspoint(v1);
     459         c2.p=u1.crosspoint(v2);
     460         c3.p=u2.crosspoint(v1);
     461         c4.p=u2.crosspoint(v2);
     462         return 4;
     463     }
     464     //同时与不相交圆cx,cy相切 半径为r1的圆
     465     int getcircle(circle cx,circle cy,double r1,circle&c1,circle&c2)
     466     {
     467         circle x(cx.p,r1+cx.r),y(cy.p,r1+cy.r);
     468         int t=x.pointcrosscircle(y,c1.p,c2.p);
     469         if (!t)return 0;
     470         c1.r=c2.r=r1;
     471         return t;
     472     }
     473     int pointcrossline(line v,point &p1,point &p2)//求与线段交要先判断relationseg
     474     {
     475         if (!(*this).relationline(v))return 0;
     476         point a=v.lineprog(p);
     477         double d=v.dispointtoline(p);
     478         d=sqrt(r*r-d*d);
     479         if (dblcmp(d)==0)
     480         {
     481             p1=a;
     482             p2=a;
     483             return 1;
     484         }
     485         p1=a.sub(v.b.sub(v.a).trunc(d));
     486         p2=a.add(v.b.sub(v.a).trunc(d));
     487         return 2;
     488     }
     489     //5 相离
     490     //4 外切
     491     //3 相交
     492     //2 内切
     493     //1 内含
     494     int relationcircle(circle v)
     495     {
     496         double d=p.distance(v.p);
     497         if (dblcmp(d-r-v.r)>0)return 5;
     498         if (dblcmp(d-r-v.r)==0)return 4;
     499         double l=fabs(r-v.r);
     500         if (dblcmp(d-r-v.r)<0&&dblcmp(d-l)>0)return 3;
     501         if (dblcmp(d-l)==0)return 2;
     502         if (dblcmp(d-l)<0)return 1;
     503     }
     504     int pointcrosscircle(circle v,point &p1,point &p2)
     505     {
     506         int rel=relationcircle(v);
     507         if (rel==1||rel==5)return 0;
     508         double d=p.distance(v.p);
     509         double l=(d+(sqr(r)-sqr(v.r))/d)/2;
     510         double h=sqrt(sqr(r)-sqr(l));
     511         p1=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotleft().trunc(h)));
     512         p2=p.add(v.p.sub(p).trunc(l).add(v.p.sub(p).rotright().trunc(h)));
     513         if (rel==2||rel==4)
     514         {
     515             return 1;
     516         }
     517         return 2;
     518     }
     519     //过一点做圆的切线 (先判断点和圆关系)
     520     int tangentline(point q,line &u,line &v)
     521     {
     522         int x=relation(q);
     523         if (x==2)return 0;
     524         if (x==1)
     525         {
     526             u=line(q,q.add(q.sub(p).rotleft()));
     527             v=u;
     528             return 1;
     529         }
     530         double d=p.distance(q);
     531         double l=sqr(r)/d;
     532         double h=sqrt(sqr(r)-sqr(l));
     533         u=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotleft().trunc(h))));
     534         v=line(q,p.add(q.sub(p).trunc(l).add(q.sub(p).rotright().trunc(h))));
     535         return 2;
     536     }
     537     double areacircle(circle v)
     538     {
     539         int rel=relationcircle(v);
     540         if (rel>=4)return 0.0;
     541         if (rel<=2)return min(area(),v.area());
     542         double d=p.distance(v.p);
     543         double hf=(r+v.r+d)/2.0;
     544         double ss=2*sqrt(hf*(hf-r)*(hf-v.r)*(hf-d));
     545         double a1=acos((r*r+d*d-v.r*v.r)/(2.0*r*d));
     546         a1=a1*r*r;
     547         double a2=acos((v.r*v.r+d*d-r*r)/(2.0*v.r*d));
     548         a2=a2*v.r*v.r;
     549         return a1+a2-ss;
     550     }
     551     double areatriangle(point a,point b)
     552     {
     553         if (dblcmp(p.sub(a).det(p.sub(b))==0))return 0.0;
     554         point q[5];
     555         int len=0;
     556         q[len++]=a;
     557         line l(a,b);
     558         point p1,p2;
     559         if (pointcrossline(l,q[1],q[2])==2)
     560         {
     561             if (dblcmp(a.sub(q[1]).dot(b.sub(q[1])))<0)q[len++]=q[1];
     562             if (dblcmp(a.sub(q[2]).dot(b.sub(q[2])))<0)q[len++]=q[2];
     563         }
     564         q[len++]=b;
     565         if (len==4&&(dblcmp(q[0].sub(q[1]).dot(q[2].sub(q[1])))>0))swap(q[1],q[2]);
     566         double res=0;
     567         int i;
     568         for (i=0;i<len-1;i++)
     569         {
     570             if (relation(q[i])==0||relation(q[i+1])==0)
     571             {
     572                 double arg=p.rad(q[i],q[i+1]);
     573                 res+=r*r*arg/2.0;
     574             }
     575             else
     576             {
     577                 res+=fabs(q[i].sub(p).det(q[i+1].sub(p))/2.0);
     578             }
     579         }
     580         return res;
     581     }
     582 };
     583 
     584 struct polygon
     585 {
     586     int n;
     587     point p[maxp];
     588     line l[maxp];
     589     void input(int X)
     590     {
     591         n=X;
     592         for (int i=0;i<n;i++)
     593         {
     594             p[i].input();
     595         }
     596     }
     597     void add(point q)
     598     {
     599         p[n++]=q;
     600     }
     601     void getline()
     602     {
     603         for (int i=0;i<n;i++)
     604         {
     605             l[i]=line(p[i],p[(i+1)%n]);
     606         }
     607     }
     608     struct cmp
     609     {
     610         point p;
     611         cmp(const point &p0){p=p0;}
     612         bool operator()(const point &aa,const point &bb)
     613         {
     614             point a=aa,b=bb;
     615             int d=dblcmp(a.sub(p).det(b.sub(p)));
     616             if (d==0)
     617             {
     618                 return dblcmp(a.distance(p)-b.distance(p))<0;
     619             }
     620             return d>0;
     621         }
     622     };
     623     void norm()
     624     {
     625         point mi=p[0];
     626         for (int i=1;i<n;i++)mi=min(mi,p[i]);
     627         sort(p,p+n,cmp(mi));
     628     }
     629     void getconvex(polygon &convex)
     630     {
     631         int i,j,k;
     632         sort(p,p+n);
     633         convex.n=n;
     634         for (i=0;i<min(n,2);i++)
     635         {
     636             convex.p[i]=p[i];
     637         }
     638         if (n<=2)return;
     639         int &top=convex.n;
     640         top=1;
     641         for (i=2;i<n;i++)
     642         {
     643             while (top&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
     644                 top--;
     645             convex.p[++top]=p[i];
     646         }
     647         int temp=top;
     648         convex.p[++top]=p[n-2];
     649         for (i=n-3;i>=0;i--)
     650         {
     651             while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0)
     652                 top--;
     653             convex.p[++top]=p[i];
     654         }
     655     }
     656 
     657     //ADD
     658     //a new oonvex algorithm
     659 /*  void Graham(polygon &convex)
     660     {
     661         norm();
     662         int &top=convex.n;
     663         top=0;
     664         if (n==1)
     665         {
     666             top=1;
     667             convex.p[0]=p[0];
     668             return;
     669         }
     670         if (n==2)
     671         {
     672             top=2;
     673             convex.p[0]=p[0];
     674             convex.p[1]=p[1];
     675             if (convex.p[0]==convex.p[1])   top--;
     676             return;
     677         }
     678         convex.p[0]=p[0];
     679         convex.p[1]=p[1];
     680         top=2;
     681         for (int i=2;i<n;i++)
     682         {
     683             while (top>1 && sgn((convex.p[top-1]-convex.p[top-2])^(p[i]-convex.p[top-2]))<=0)
     684                 top--;
     685             convex.p[top++]=p[i];
     686         }
     687         if (convex.n==2 && (convex.p[0]==convex.p[1]))  convex.n--;
     688     }
     689 */
     690     bool isconvex()
     691     {
     692         bool s[3];
     693         memset(s,0,sizeof(s));
     694         int i,j,k;
     695         for (i=0;i<n;i++)
     696         {
     697             j=(i+1)%n;
     698             k=(j+1)%n;
     699             s[dblcmp(p[j].sub(p[i]).det(p[k].sub(p[i])))+1]=1;
     700             if (s[0]&&s[2])return 0;
     701         }
     702         return 1;
     703     }
     704     //3 点上
     705     //2 边上
     706     //1 内部
     707     //0 外部
     708     int relationpoint(point q)
     709     {
     710         int i,j;
     711         for (i=0;i<n;i++)
     712         {
     713             if (p[i]==q)return 3;
     714         }
     715         getline();
     716         for (i=0;i<n;i++)
     717         {
     718             if (l[i].pointonseg(q))return 2;
     719         }
     720         int cnt=0;
     721         for (i=0;i<n;i++)
     722         {
     723             j=(i+1)%n;
     724             int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j])));
     725             int u=dblcmp(p[i].y-q.y);
     726             int v=dblcmp(p[j].y-q.y);
     727             if (k>0&&u<0&&v>=0)cnt++;
     728             if (k<0&&v<0&&u>=0)cnt--;
     729         }
     730         return cnt!=0;
     731     }
     732     //1 在多边形内长度为正
     733     //2 相交或与边平行
     734     //0 无任何交点
     735     int relationline(line u)
     736     {
     737         int i,j,k=0;
     738         getline();
     739         for (i=0;i<n;i++)
     740         {
     741             if (l[i].segcrossseg(u)==2)return 1;
     742             if (l[i].segcrossseg(u)==1)k=1;
     743         }
     744         if (!k)return 0;
     745         vector<point>vp;
     746         for (i=0;i<n;i++)
     747         {
     748             if (l[i].segcrossseg(u))
     749             {
     750                 if (l[i].parallel(u))
     751                 {
     752                     vp.pb(u.a);
     753                     vp.pb(u.b);
     754                     vp.pb(l[i].a);
     755                     vp.pb(l[i].b);
     756                     continue;
     757                 }
     758                 vp.pb(l[i].crosspoint(u));
     759             }
     760         }
     761         sort(vp.begin(),vp.end());
     762         int sz=vp.size();
     763         for (i=0;i<sz-1;i++)
     764         {
     765             point mid=vp[i].add(vp[i+1]).div(2);
     766             if (relationpoint(mid)==1)return 1;
     767         }
     768         return 2;
     769     }
     770     //直线u切割凸多边形左侧
     771     //注意直线方向
     772     void convexcut(line u,polygon &po)
     773     {
     774         int i,j,k;
     775         int &top=po.n;
     776         top=0;
     777         for (i=0;i<n;i++)
     778         {
     779             int d1=dblcmp(p[i].sub(u.a).det(u.b.sub(u.a)));
     780             int d2=dblcmp(p[(i+1)%n].sub(u.a).det(u.b.sub(u.a)));
     781             if (d1>=0)po.p[top++]=p[i];
     782             if (d1*d2<0)po.p[top++]=u.crosspoint(line(p[i],p[(i+1)%n]));
     783         }
     784     }
     785     double getcircumference()
     786     {
     787         double sum=0;
     788         int i;
     789         for (i=0;i<n;i++)
     790         {
     791             sum+=p[i].distance(p[(i+1)%n]);
     792         }
     793         return sum;
     794     }
     795     double getarea()
     796     {
     797         double sum=0;
     798         int i;
     799         for (i=0;i<n;i++)
     800         {
     801             sum+=p[i].det(p[(i+1)%n]);
     802         }
     803         return fabs(sum)/2;
     804     }
     805     bool getdir()//1代表逆时针 0代表顺时针
     806     {
     807         double sum=0;
     808         int i;
     809         for (i=0;i<n;i++)
     810         {
     811             sum+=p[i].det(p[(i+1)%n]);
     812         }
     813         if (dblcmp(sum)>0)return 1;
     814         return 0;
     815     }
     816     point getbarycentre()
     817     {
     818         point ret(0,0);
     819         double area=0;
     820         int i;
     821         for (i=1;i<n-1;i++)
     822         {
     823             double tmp=p[i].sub(p[0]).det(p[i+1].sub(p[0]));
     824             if (dblcmp(tmp)==0)continue;
     825             area+=tmp;
     826             ret.x+=(p[0].x+p[i].x+p[i+1].x)/3*tmp;
     827             ret.y+=(p[0].y+p[i].y+p[i+1].y)/3*tmp;
     828         }
     829         if (dblcmp(area))ret=ret.div(area);
     830         return ret;
     831     }
     832     /*      shen me gui !
     833     double areaintersection(polygon po)
     834     {
     835     }
     836     double areaunion(polygon po)
     837     {
     838         return getarea()+po.getarea()-areaintersection(po);
     839     }
     840     */
     841     double areacircle(circle c)
     842     {
     843         int i,j,k,l,m;
     844         double ans=0;
     845         for (i=0;i<n;i++)
     846         {
     847             int j=(i+1)%n;
     848             if (dblcmp(p[j].sub(c.p).det(p[i].sub(c.p)))>=0)
     849             {
     850                 ans+=c.areatriangle(p[i],p[j]);
     851             }
     852             else
     853             {
     854                 ans-=c.areatriangle(p[i],p[j]);
     855             }
     856         }
     857         return fabs(ans);
     858     }
     859     //多边形和圆关系
     860     //0 一部分在圆外
     861     //1 与圆某条边相切
     862     //2 完全在圆内
     863     int relationcircle(circle c)
     864     {
     865         getline();
     866         int i,x=2;
     867         if (relationpoint(c.p)!=1)return 0;
     868         for (i=0;i<n;i++)
     869         {
     870             if (c.relationseg(l[i])==2)return 0;
     871             if (c.relationseg(l[i])==1)x=1;
     872         }
     873         return x;
     874     }
     875     void find(int st,point tri[],circle &c)
     876     {
     877         if (!st)
     878         {
     879             c=circle(point(0,0),-2);
     880         }
     881         if (st==1)
     882         {
     883             c=circle(tri[0],0);
     884         }
     885         if (st==2)
     886         {
     887             c=circle(tri[0].add(tri[1]).div(2),tri[0].distance(tri[1])/2.0);
     888         }
     889         if (st==3)
     890         {
     891             c=circle(tri[0],tri[1],tri[2]);
     892         }
     893     }
     894     void solve(int cur,int st,point tri[],circle &c)
     895     {
     896         find(st,tri,c);
     897         if (st==3)return;
     898         int i;
     899         for (i=0;i<cur;i++)
     900         {
     901             if (dblcmp(p[i].distance(c.p)-c.r)>0)
     902             {
     903                 tri[st]=p[i];
     904                 solve(i,st+1,tri,c);
     905             }
     906         }
     907     }
     908     circle mincircle()//点集最小圆覆盖
     909     {
     910         random_shuffle(p,p+n);
     911         point tri[4];
     912         circle c;
     913         solve(n,0,tri,c);
     914         return c;
     915     }
     916     int circlecover(double r)//单位圆覆盖
     917     {
     918         int ans=0,i,j;
     919         vector<pair<double,int> >v;
     920         for (i=0;i<n;i++)
     921         {
     922             v.clear();
     923             for (j=0;j<n;j++)if (i!=j)
     924             {
     925                 point q=p[i].sub(p[j]);
     926                 double d=q.len();
     927                 if (dblcmp(d-2*r)<=0)
     928                 {
     929                     double arg=atan2(q.y,q.x);
     930                     if (dblcmp(arg)<0)arg+=2*pi;
     931                     double t=acos(d/(2*r));
     932                     v.push_back(make_pair(arg-t+2*pi,-1));
     933                     v.push_back(make_pair(arg+t+2*pi,1));
     934                 }
     935             }
     936             sort(v.begin(),v.end());
     937             int cur=0;
     938             for (j=0;j<v.size();j++)
     939             {
     940                 if (v[j].second==-1)++cur;
     941                 else --cur;
     942                 ans=max(ans,cur);
     943             }
     944         }
     945         return ans+1;
     946     }
     947     int pointinpolygon(point q)//点在凸多边形内部的判定
     948     {
     949         if (getdir())reverse(p,p+n);
     950         if (dblcmp(q.sub(p[0]).det(p[n-1].sub(p[0])))==0)
     951         {
     952             if (line(p[n-1],p[0]).pointonseg(q))return n-1;
     953             return -1;
     954         }
     955         int low=1,high=n-2,mid;
     956         while (low<=high)
     957         {
     958             mid=(low+high)>>1;
     959             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>=0&&dblcmp(q.sub(p[0]).det(p[mid+1].sub(p[0])))<0)
     960             {
     961                 polygon c;
     962                 c.p[0]=p[mid];
     963                 c.p[1]=p[mid+1];
     964                 c.p[2]=p[0];
     965                 c.n=3;
     966                 if (c.relationpoint(q))return mid;
     967                 return -1;
     968             }
     969             if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>0)
     970             {
     971                 low=mid+1;
     972             }
     973             else
     974             {
     975                 high=mid-1;
     976             }
     977         }
     978         return -1;
     979     }
     980 
     981     //ADD
     982     //最小矩形面积覆盖
     983     //A必须是凸包(而且是逆时针顺序)
     984     //Uva   10173
     985     double cross(point A,point B,point C)
     986     {}
     987     double dot(point A,point B,point C)
     988     {}
     989     double minRectangleCover(polygon A)
     990     {}
     991 
     992     //ADD
     993     //直线切凸多边形
     994     //多边形是逆时针的,在q1q2的左侧
     995     //HDU3982
     996     /*
     997     vector<point> convexcut(const vector<point> &ps,point q1,point q2)
     998     {
     999         vector<point> qs;
    1000         int n=ps.size();
    1001         for (int i=0;i<n;i++)
    1002         {
    1003             point p1=ps[i],p2=ps[(i+1)%n];
    1004             int d1=sgn((q2-q1)^(p1-q1)),d2=sgn((q2-q1)^(p2-q1));
    1005             if (d1>=0)
    1006                 qs.push_back(p1);
    1007             if (d1*d2<0)
    1008                 qs.push_back(line(p1,p2).crosspoint(line(q1,q2)));
    1009         }
    1010         return qs;
    1011     }
    1012     */
    1013 };
    1014 
    1015 //ADD
    1016 //直线切凸多边形
    1017 //多边形是逆时针的,在q1q2的左侧
    1018 //HDU3982
    1019 vector<point> convexcut(const vector<point> &ps,point q1,point q2)
    1020 {
    1021     vector<point> qs;
    1022     int n=ps.size();
    1023     for (int i=0; i<n; i++)
    1024     {
    1025         point p1=ps[i],p2=ps[(i+1)%n];
    1026         int d1=sgn((q2-q1)^(p1-q1)),d2=sgn((q2-q1)^(p2-q1));
    1027         if (d1>=0)
    1028             qs.push_back(p1);
    1029         if (d1*d2<0)
    1030             qs.push_back(line(p1,p2).crosspoint(line(q1,q2)));
    1031     }
    1032     return qs;
    1033 }
    1034 
    1035 double CutLine[10000][10];
    1036 point Cherry;
    1037 int TotalTimes,n;
    1038 double r;
    1039 
    1040 int main()
    1041 {
    1042     freopen("in.txt","r",stdin);
    1043 
    1044     cin>>TotalTimes;
    1045     for (int Times=1;Times<=TotalTimes;Times++)
    1046     {
    1047         //cin>>r>>n;
    1048         scanf("%lf%d",&r,&n);
    1049         circle Cake=circle(point(0.00,0.00),r);
    1050         vector<point> BigPolygon;
    1051         BigPolygon.push_back(point(-r,r));
    1052         BigPolygon.push_back(point(-r,-r));
    1053         BigPolygon.push_back(point(r,-r));
    1054         BigPolygon.push_back(point(r,r));
    1055 
    1056         for (int i=1;i<=n;i++)
    1057             scanf("%lf%lf%lf%lf",&CutLine[i][1],&CutLine[i][2],&CutLine[i][3],&CutLine[i][4]);
    1058             //cin>>CutLine[i][1]>>CutLine[i][2]>>CutLine[i][3]>>CutLine[i][4];
    1059 
    1060         Cherry.input();
    1061 
    1062         for (int i=1;i<=n;i++)
    1063         {
    1064             line cut(point(CutLine[i][1],CutLine[i][2]),point(CutLine[i][3],CutLine[i][4]));
    1065             if (cut.relation(Cherry)==2)
    1066             {
    1067                 //cut=line(point(CutLine[i][3],CutLine[i][4]),point(CutLine[i][1],CutLine[i][2]));
    1068                 BigPolygon=convexcut(BigPolygon,point(CutLine[i][3],CutLine[i][4]),point(CutLine[i][1],CutLine[i][2]));
    1069             }
    1070             else
    1071             {
    1072                 BigPolygon=convexcut(BigPolygon,point(CutLine[i][1],CutLine[i][2]),point(CutLine[i][3],CutLine[i][4]));
    1073             }
    1074         }
    1075 
    1076         polygon Bigpolygon;     Bigpolygon.n=0;
    1077         for (vector<point>::iterator i=BigPolygon.begin();i!=BigPolygon.end();i++)
    1078         {
    1079             point tmp=*i;
    1080             Bigpolygon.add(tmp);
    1081         }
    1082         //double ans=Bigpolygon.getarea();
    1083         double CakeArea=Cake.area();
    1084         double ans=Bigpolygon.areacircle(Cake);
    1085         ans=ans/CakeArea*100;
    1086         printf("Case %d: %.5lf%%
    ",Times,ans);
    1087     }
    1088     return 0;
    1089 }
    View Code

    Reference:http://blog.csdn.net/zxy_snow/article/details/6739561

    话说自从开始刷计算几何之后发现自己代码风格越来越屎了,满满的工程代码既视感。。【逃

  • 相关阅读:
    ASP.NET MVC3 中设置htmlAttribute
    oracle查看表空间的几个sql
    SQL Server 中 sysobjects表
    Openal简介
    [转]DBUSGLIB Binding,GLIB事件与DBUS事件是如何关联的
    ffmpeg简介
    ffmpeg安装FAAC
    ffserver error
    Openal教程(二)
    centos下安装qt时出现/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found
  • 原文地址:https://www.cnblogs.com/pdev/p/4286912.html
Copyright © 2011-2022 走看看