poj2318
题意:把一个矩形划分成n部分,再给出一堆点,求每个部分内落入了多少点
sol attempt1:暴力
注意每个polygon中的点要按笔画的顺序排列好。还有就是有的点可能落在了upper or lower edge,稍微处理一下(ans==1 or 2都算)
TLE了 -_-||
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 #define MAXN 5010 31 using namespace std; 32 const double eps=1e-8; 33 const double pi=acos(-1.0); 34 const double inf=1e20; 35 const int maxp=10; //多边形内点的数量,注意按需求调整 36 37 int sgn(double x) 38 { 39 if (fabs(x)<eps) return 0; 40 if (x<0) return -1; 41 else return 1; 42 } 43 44 int dblcmp(double d) 45 { 46 if (fabs(d)<eps)return 0; 47 return d>eps?1:-1; 48 } 49 50 inline double sqr(double x){return x*x;} 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.y-y*b.x; 93 } 94 double operator *(const point &b)const 95 { 96 return x*b.x+y*b.y; 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 //注意:点必须按顺序读入,否则在getline的时候会混乱掉 602 void getline() 603 { 604 for (int i=0;i<n;i++) 605 { 606 l[i]=line(p[i],p[(i+1)%n]); 607 } 608 } 609 struct cmp 610 { 611 point p; 612 cmp(const point &p0){p=p0;} 613 bool operator()(const point &aa,const point &bb) 614 { 615 point a=aa,b=bb; 616 int d=dblcmp(a.sub(p).det(b.sub(p))); 617 if (d==0) 618 { 619 return dblcmp(a.distance(p)-b.distance(p))<0; 620 } 621 return d>0; 622 } 623 }; 624 void norm() 625 { 626 point mi=p[0]; 627 for (int i=1;i<n;i++)mi=min(mi,p[i]); 628 sort(p,p+n,cmp(mi)); 629 } 630 void getconvex(polygon &convex) 631 { 632 int i,j,k; 633 sort(p,p+n); 634 convex.n=n; 635 for (i=0;i<min(n,2);i++) 636 { 637 convex.p[i]=p[i]; 638 } 639 if (n<=2)return; 640 int &top=convex.n; 641 top=1; 642 for (i=2;i<n;i++) 643 { 644 while (top&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0) 645 top--; 646 convex.p[++top]=p[i]; 647 } 648 int temp=top; 649 convex.p[++top]=p[n-2]; 650 for (i=n-3;i>=0;i--) 651 { 652 while (top!=temp&&convex.p[top].sub(p[i]).det(convex.p[top-1].sub(p[i]))<=0) 653 top--; 654 convex.p[++top]=p[i]; 655 } 656 } 657 bool isconvex() 658 { 659 bool s[3]; 660 memset(s,0,sizeof(s)); 661 int i,j,k; 662 for (i=0;i<n;i++) 663 { 664 j=(i+1)%n; 665 k=(j+1)%n; 666 s[dblcmp(p[j].sub(p[i]).det(p[k].sub(p[i])))+1]=1; 667 if (s[0]&&s[2])return 0; 668 } 669 return 1; 670 } 671 //3 点上 672 //2 边上 673 //1 内部 674 //0 外部 675 int relationpoint(point q) 676 { 677 int i,j; 678 for (i=0;i<n;i++) 679 { 680 if (p[i]==q)return 3; 681 } 682 getline(); 683 for (i=0;i<n;i++) 684 { 685 if (l[i].pointonseg(q)) 686 { 687 //cout<<"222: "<<i<<" "<<l[i].a.x<<","<<l[i].a.y<<"---"<<l[i].b.x<<","<<l[i].b.y<<endl; 688 return 2; 689 } 690 } 691 int cnt=0; 692 for (i=0;i<n;i++) 693 { 694 j=(i+1)%n; 695 int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j]))); 696 int u=dblcmp(p[i].y-q.y); 697 int v=dblcmp(p[j].y-q.y); 698 if (k>0&&u<0&&v>=0)cnt++; 699 if (k<0&&v<0&&u>=0)cnt--; 700 } 701 return cnt!=0; 702 } 703 //1 在多边形内长度为正 704 //2 相交或与边平行 705 //0 无任何交点 706 int relationline(line u) 707 { 708 int i,j,k=0; 709 getline(); 710 for (i=0;i<n;i++) 711 { 712 if (l[i].segcrossseg(u)==2)return 1; 713 if (l[i].segcrossseg(u)==1)k=1; 714 } 715 if (!k)return 0; 716 vector<point>vp; 717 for (i=0;i<n;i++) 718 { 719 if (l[i].segcrossseg(u)) 720 { 721 if (l[i].parallel(u)) 722 { 723 vp.pb(u.a); 724 vp.pb(u.b); 725 vp.pb(l[i].a); 726 vp.pb(l[i].b); 727 continue; 728 } 729 vp.pb(l[i].crosspoint(u)); 730 } 731 } 732 sort(vp.begin(),vp.end()); 733 int sz=vp.size(); 734 for (i=0;i<sz-1;i++) 735 { 736 point mid=vp[i].add(vp[i+1]).div(2); 737 if (relationpoint(mid)==1)return 1; 738 } 739 return 2; 740 } 741 //直线u切割凸多边形左侧 742 //注意直线方向 743 void convexcut(line u,polygon &po) 744 { 745 int i,j,k; 746 int &top=po.n; 747 top=0; 748 for (i=0;i<n;i++) 749 { 750 int d1=dblcmp(p[i].sub(u.a).det(u.b.sub(u.a))); 751 int d2=dblcmp(p[(i+1)%n].sub(u.a).det(u.b.sub(u.a))); 752 if (d1>=0)po.p[top++]=p[i]; 753 if (d1*d2<0)po.p[top++]=u.crosspoint(line(p[i],p[(i+1)%n])); 754 } 755 } 756 double getcircumference() 757 { 758 double sum=0; 759 int i; 760 for (i=0;i<n;i++) 761 { 762 sum+=p[i].distance(p[(i+1)%n]); 763 } 764 return sum; 765 } 766 double getarea() 767 { 768 double sum=0; 769 int i; 770 for (i=0;i<n;i++) 771 { 772 sum+=p[i].det(p[(i+1)%n]); 773 } 774 return fabs(sum)/2; 775 } 776 bool getdir()//1代表逆时针 0代表顺时针 777 { 778 double sum=0; 779 int i; 780 for (i=0;i<n;i++) 781 { 782 sum+=p[i].det(p[(i+1)%n]); 783 } 784 if (dblcmp(sum)>0)return 1; 785 return 0; 786 } 787 point getbarycentre() 788 { 789 point ret(0,0); 790 double area=0; 791 int i; 792 for (i=1;i<n-1;i++) 793 { 794 double tmp=p[i].sub(p[0]).det(p[i+1].sub(p[0])); 795 if (dblcmp(tmp)==0)continue; 796 area+=tmp; 797 ret.x+=(p[0].x+p[i].x+p[i+1].x)/3*tmp; 798 ret.y+=(p[0].y+p[i].y+p[i+1].y)/3*tmp; 799 } 800 if (dblcmp(area))ret=ret.div(area); 801 return ret; 802 } 803 double areaintersection(polygon po) 804 { 805 } 806 double areaunion(polygon po) 807 { 808 return getarea()+po.getarea()-areaintersection(po); 809 } 810 double areacircle(circle c) 811 { 812 int i,j,k,l,m; 813 double ans=0; 814 for (i=0;i<n;i++) 815 { 816 int j=(i+1)%n; 817 if (dblcmp(p[j].sub(c.p).det(p[i].sub(c.p)))>=0) 818 { 819 ans+=c.areatriangle(p[i],p[j]); 820 } 821 else 822 { 823 ans-=c.areatriangle(p[i],p[j]); 824 } 825 } 826 return fabs(ans); 827 } 828 //多边形和圆关系 829 //0 一部分在圆外 830 //1 与圆某条边相切 831 //2 完全在圆内 832 int relationcircle(circle c) 833 { 834 getline(); 835 int i,x=2; 836 if (relationpoint(c.p)!=1)return 0; 837 for (i=0;i<n;i++) 838 { 839 if (c.relationseg(l[i])==2)return 0; 840 if (c.relationseg(l[i])==1)x=1; 841 } 842 return x; 843 } 844 void find(int st,point tri[],circle &c) 845 { 846 if (!st) 847 { 848 c=circle(point(0,0),-2); 849 } 850 if (st==1) 851 { 852 c=circle(tri[0],0); 853 } 854 if (st==2) 855 { 856 c=circle(tri[0].add(tri[1]).div(2),tri[0].distance(tri[1])/2.0); 857 } 858 if (st==3) 859 { 860 c=circle(tri[0],tri[1],tri[2]); 861 } 862 } 863 void solve(int cur,int st,point tri[],circle &c) 864 { 865 find(st,tri,c); 866 if (st==3)return; 867 int i; 868 for (i=0;i<cur;i++) 869 { 870 if (dblcmp(p[i].distance(c.p)-c.r)>0) 871 { 872 tri[st]=p[i]; 873 solve(i,st+1,tri,c); 874 } 875 } 876 } 877 circle mincircle()//点集最小圆覆盖 878 { 879 random_shuffle(p,p+n); 880 point tri[4]; 881 circle c; 882 solve(n,0,tri,c); 883 return c; 884 } 885 int circlecover(double r)//单位圆覆盖 886 { 887 int ans=0,i,j; 888 vector<pair<double,int> >v; 889 for (i=0;i<n;i++) 890 { 891 v.clear(); 892 for (j=0;j<n;j++)if (i!=j) 893 { 894 point q=p[i].sub(p[j]); 895 double d=q.len(); 896 if (dblcmp(d-2*r)<=0) 897 { 898 double arg=atan2(q.y,q.x); 899 if (dblcmp(arg)<0)arg+=2*pi; 900 double t=acos(d/(2*r)); 901 v.push_back(make_pair(arg-t+2*pi,-1)); 902 v.push_back(make_pair(arg+t+2*pi,1)); 903 } 904 } 905 sort(v.begin(),v.end()); 906 int cur=0; 907 for (j=0;j<v.size();j++) 908 { 909 if (v[j].second==-1)++cur; 910 else --cur; 911 ans=max(ans,cur); 912 } 913 } 914 return ans+1; 915 } 916 int pointinpolygon(point q)//点在凸多边形内部的判定 917 { 918 if (getdir())reverse(p,p+n); 919 if (dblcmp(q.sub(p[0]).det(p[n-1].sub(p[0])))==0) 920 { 921 if (line(p[n-1],p[0]).pointonseg(q))return n-1; 922 return -1; 923 } 924 int low=1,high=n-2,mid; 925 while (low<=high) 926 { 927 mid=(low+high)>>1; 928 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) 929 { 930 polygon c; 931 c.p[0]=p[mid]; 932 c.p[1]=p[mid+1]; 933 c.p[2]=p[0]; 934 c.n=3; 935 if (c.relationpoint(q))return mid; 936 return -1; 937 } 938 if (dblcmp(q.sub(p[0]).det(p[mid].sub(p[0])))>0) 939 { 940 low=mid+1; 941 } 942 else 943 { 944 high=mid-1; 945 } 946 } 947 return -1; 948 } 949 }; 950 951 952 struct polygon PL[MAXN]; 953 struct point PO[MAXN]; 954 int num[MAXN]; 955 int n,m; 956 double X1,Y1,X2,Y2; 957 double L[MAXN],U[MAXN]; 958 959 int main() 960 { 961 while(scanf("%d",&n)) 962 { 963 if(n==0) break; 964 scanf("%d%lf%lf%lf%lf",&m,&X1,&Y1,&X2,&Y2); 965 for (int i=0; i<n; i++) 966 scanf("%lf%lf",&U[i],&L[i]); 967 for (int i=0; i<m; i++) 968 PO[i].input(); 969 970 sort(U,U+n); 971 sort(L,L+n); 972 973 for (int i=0; i<=n; i++) 974 { 975 int ya=Y1,yb=Y2,yc=Y2,yd=Y1; 976 int xa,xb,xc,xd; 977 if (i==0) 978 { 979 xa=X1,xb=X1; 980 xc=L[0],xd=U[0]; 981 } 982 else if (i==n) 983 { 984 xa=U[n-1],xb=L[n-1]; 985 xc=X2,xd=X2; 986 } 987 else 988 { 989 xa=U[i-1],xb=L[i-1]; 990 xc=L[i],xd=U[i]; 991 } 992 PL[i].n=4; 993 PL[i].p[0]=point(xa,ya); 994 PL[i].p[1]=point(xb,yb); 995 PL[i].p[2]=point(xc,yc); 996 PL[i].p[3]=point(xd,yd); 997 PL[i].getline(); 998 } 999 //PL[0..n]:polygon 1000 1001 memset(num,0,sizeof(num)); 1002 for (int i=0;i<=n;i++) 1003 { 1004 polygon PY=PL[i]; 1005 PY.getline(); 1006 /* 1007 cout<<"PL "; 1008 for (int j=0;j<=3;j++) 1009 cout<<PY.p[j].x<<","<<PY.p[j].y<<" "; 1010 cout<<endl; 1011 */ 1012 for (int j=0;j<m;j++) 1013 { 1014 point PPP=PO[j]; 1015 int ans=PY.relationpoint(PPP); 1016 //cout<<PPP.x<<","<<PPP.y<<" "<<ans<<endl; 1017 if ((ans==1)||(ans==2)) 1018 num[i]++; 1019 } 1020 1021 } 1022 1023 for (int i=0; i<=n; i++) 1024 printf("%d: %d\n",i,num[i]); 1025 //cout<<i<<": "<<num[i]<<endl; 1026 } 1027 return 0; 1028 }
sol attemp2:可以二分啊
对于每一个点,判断当前线段在点的左边还是右边
posted on 2015-05-01 19:52 Pentium.Labs 阅读(346) 评论(0) 编辑 收藏 举报