标签:
题意:有一块蛋糕,上面有一颗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\n",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\n",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%%\n",Times,ans); 1087 } 1088 return 0; 1089 }
Reference:http://blog.csdn.net/zxy_snow/article/details/6739561
话说自从开始刷计算几何之后发现自己代码风格越来越屎了,满满的工程代码既视感。。【逃
标签:
原文地址:http://www.cnblogs.com/pdev/p/4286912.html