Pentium.Labs

System全家桶:https://zhuanlan.zhihu.com/c_1238468913098731520

导航

poj2318

题意:把一个矩形划分成n部分,再给出一堆点,求每个部分内落入了多少点

 

sol attempt1:暴力

注意每个polygon中的点要按笔画的顺序排列好。还有就是有的点可能落在了upper or lower edge,稍微处理一下(ans==1 or 2都算)

TLE了 -_-||

   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 }
View Code

 

sol attemp2:可以二分啊

对于每一个点,判断当前线段在点的左边还是右边

posted on 2015-05-01 19:52  Pentium.Labs  阅读(347)  评论(0编辑  收藏  举报



Pentium.Lab Since 1998