• xcoj1062


    题意:给出一个闭合折线上的一堆点(不按顺序),然后再给一个点P,要求判断P是否在闭合折线内

    sol attempt1:一开始觉得是个模板题的,后来发现不对劲:

    给出的点并不按照顺序。这样模板大法就不行了(geiline函数是按顺序建line的,会错乱掉)

    sol attempt2:手艹大法:先建立好图形,然后再判断:

    从点P向外引射线,若射线与图形的边相交奇数次,说明P在图形内。

    PS:本题测试数据好像有点不对劲:

    对于这组数据:

    12
    0 40
    0 50
    0 0
    10 10
    0 30
    0 20
    0 10
    10 40
    20 50
    20 0
    10 20
    10 30
    10 1

    很容易画出图:

    很容易发现绿色点P应该是INSIDE的,但是testdata是OUTSIDE

    围观了下标程。。。好像是对于多组数据标程忘了初始化数组了。当时现场也并没有人过orz

    附我的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-8;
     32 const double pi=acos(-1.0);
     33 const double inf=1e20;
     34 const int maxp=10010;    //多边形内点的数量,注意按需求调整
     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 struct point
     51 {
     52     double x,y;
     53     point(){}
     54     point(double _x,double _y):
     55     x(_x),y(_y){};
     56     void input()
     57     {
     58         scanf("%lf%lf",&x,&y);
     59     }
     60     void output()
     61     {
     62         printf("%.2f %.2f
    ",x,y);
     63     }
     64     bool operator==(point a)const
     65     {
     66         return dblcmp(a.x-x)==0&&dblcmp(a.y-y)==0;
     67     }
     68     bool operator<(point a)const
     69     {
     70         return dblcmp(a.x-x)==0?dblcmp(y-a.y)<0:x<a.x;
     71     }
     72 
     73     point operator +(const point &b)const
     74     {
     75         return point(x+b.x,y+b.y);
     76     }
     77     point operator -(const point &b)const
     78     {
     79         return point(x-b.x,y-b.y);
     80     }
     81     point operator *(const double &k)const
     82     {
     83         return point(x*k,y*k);
     84     }
     85     point operator /(const double &k)const
     86     {
     87         return point(x/k,y/k);
     88     }
     89     double operator ^(const point &b)const
     90     {
     91         return x*b.y-y*b.x;
     92     }
     93     double operator *(const point &b)const
     94     {
     95         return x*b.x+y*b.y;
     96     }
     97 
     98     double len()
     99     {
    100         return hypot(x,y);
    101     }
    102     double len2()
    103     {
    104         return x*x+y*y;
    105     }
    106     double distance(point p)
    107     {
    108         return hypot(x-p.x,y-p.y);
    109     }
    110     point add(point p)
    111     {
    112         return point(x+p.x,y+p.y);
    113     }
    114     point sub(point p)
    115     {
    116         return point(x-p.x,y-p.y);
    117     }
    118     point mul(double b)
    119     {
    120         return point(x*b,y*b);
    121     }
    122     point div(double b)
    123     {
    124         return point(x/b,y/b);
    125     }
    126     double dot(point p)
    127     {
    128         return x*p.x+y*p.y;
    129     }
    130     double det(point p)
    131     {
    132         return x*p.y-y*p.x;
    133     }
    134     double rad(point a,point b)
    135     {
    136         point p=*this;
    137         return fabs(atan2(fabs(a.sub(p).det(b.sub(p))),a.sub(p).dot(b.sub(p))));
    138     }
    139     point trunc(double r)
    140     {
    141         double l=len();
    142         if (!dblcmp(l))return *this;
    143         r/=l;
    144         return point(x*r,y*r);
    145     }
    146     point rotleft()
    147     {
    148         return point(-y,x);
    149     }
    150     point rotright()
    151     {
    152         return point(y,-x);
    153     }
    154     point rotate(point p,double angle)//绕点p逆时针旋转angle角度
    155     {
    156         point v=this->sub(p);
    157         double c=cos(angle),s=sin(angle);
    158         return point(p.x+v.x*c-v.y*s,p.y+v.x*s+v.y*c);
    159     }
    160 };
    161 
    162 struct line
    163 {
    164     point a,b;
    165     line(){}
    166     line(point _a,point _b)
    167     {
    168         a=_a;
    169         b=_b;
    170     }
    171     bool operator==(line v)
    172     {
    173         return (a==v.a)&&(b==v.b);
    174     }
    175     //倾斜角angle
    176     line(point p,double angle)
    177     {
    178         a=p;
    179         if (dblcmp(angle-pi/2)==0)
    180         {
    181             b=a.add(point(0,1));
    182         }
    183         else
    184         {
    185             b=a.add(point(1,tan(angle)));
    186         }
    187     }
    188     //ax+by+c=0
    189     line(double _a,double _b,double _c)
    190     {
    191         if (dblcmp(_a)==0)
    192         {
    193             a=point(0,-_c/_b);
    194             b=point(1,-_c/_b);
    195         }
    196         else if (dblcmp(_b)==0)
    197         {
    198             a=point(-_c/_a,0);
    199             b=point(-_c/_a,1);
    200         }
    201         else
    202         {
    203             a=point(0,-_c/_b);
    204             b=point(1,(-_c-_a)/_b);
    205         }
    206     }
    207     void input()
    208     {
    209         a.input();
    210         b.input();
    211     }
    212     void adjust()
    213     {
    214         if (b<a)swap(a,b);
    215     }
    216     double length()
    217     {
    218         return a.distance(b);
    219     }
    220     double angle()//直线倾斜角 0<=angle<180
    221     {
    222         double k=atan2(b.y-a.y,b.x-a.x);
    223         if (dblcmp(k)<0)k+=pi;
    224         if (dblcmp(k-pi)==0)k-=pi;
    225         return k;
    226     }
    227     //点和线段关系
    228     //1 在逆时针
    229     //2 在顺时针
    230     //3 平行
    231     int relation(point p)
    232     {
    233         int c=dblcmp(p.sub(a).det(b.sub(a)));
    234         if (c<0)return 1;
    235         if (c>0)return 2;
    236         return 3;
    237     }
    238     bool pointonseg(point p)
    239     {
    240         return dblcmp(p.sub(a).det(b.sub(a)))==0&&dblcmp(p.sub(a).dot(p.sub(b)))<=0;
    241     }
    242     bool parallel(line v)
    243     {
    244         return dblcmp(b.sub(a).det(v.b.sub(v.a)))==0;
    245     }
    246     //2 规范相交
    247     //1 非规范相交
    248     //0 不相交
    249     int segcrossseg(line v)
    250     {
    251         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
    252         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
    253         int d3=dblcmp(v.b.sub(v.a).det(a.sub(v.a)));
    254         int d4=dblcmp(v.b.sub(v.a).det(b.sub(v.a)));
    255         if ((d1^d2)==-2&&(d3^d4)==-2)return 2;
    256         return (d1==0&&dblcmp(v.a.sub(a).dot(v.a.sub(b)))<=0||
    257                 d2==0&&dblcmp(v.b.sub(a).dot(v.b.sub(b)))<=0||
    258                 d3==0&&dblcmp(a.sub(v.a).dot(a.sub(v.b)))<=0||
    259                 d4==0&&dblcmp(b.sub(v.a).dot(b.sub(v.b)))<=0);
    260     }
    261     int linecrossseg(line v)//*this seg v line
    262     {
    263         int d1=dblcmp(b.sub(a).det(v.a.sub(a)));
    264         int d2=dblcmp(b.sub(a).det(v.b.sub(a)));
    265         if ((d1^d2)==-2)return 2;
    266         return (d1==0||d2==0);
    267     }
    268     //0 平行
    269     //1 重合
    270     //2 相交
    271     int linecrossline(line v)
    272     {
    273         if ((*this).parallel(v))
    274         {
    275             return v.relation(a)==3;
    276         }
    277         return 2;
    278     }
    279     point crosspoint(line v)
    280     {
    281         double a1=v.b.sub(v.a).det(a.sub(v.a));
    282         double a2=v.b.sub(v.a).det(b.sub(v.a));
    283         return point((a.x*a2-b.x*a1)/(a2-a1),(a.y*a2-b.y*a1)/(a2-a1));
    284     }
    285     double dispointtoline(point p)
    286     {
    287         return fabs(p.sub(a).det(b.sub(a)))/length();
    288     }
    289     double dispointtoseg(point p)
    290     {
    291         if (dblcmp(p.sub(b).dot(a.sub(b)))<0||dblcmp(p.sub(a).dot(b.sub(a)))<0)
    292         {
    293             return min(p.distance(a),p.distance(b));
    294         }
    295         return dispointtoline(p);
    296     }
    297     point lineprog(point p)
    298     {
    299         return a.add(b.sub(a).mul(b.sub(a).dot(p.sub(a))/b.sub(a).len2()));
    300     }
    301     point symmetrypoint(point p)
    302     {
    303         point q=lineprog(p);
    304         return point(2*q.x-p.x,2*q.y-p.y);
    305     }
    306 };
    307 
    308 struct Vector:public point
    309 {
    310     Vector(){}
    311     Vector(double a,double b)
    312     {
    313         x=a;    y=b;
    314     }
    315     Vector(point _a,point _b)   //a->b
    316     {
    317         double dx=_b.x-_a.x;
    318         double dy=_b.y-_a.y;
    319         x=dx;   y=dy;
    320     }
    321     Vector(line v)
    322     {
    323         double dx=v.b.x-v.a.x;
    324         double dy=v.b.y-v.a.y;
    325         x=dx;   y=dy;
    326     }
    327     double length()
    328     {
    329         return (sqrt(x*x+y*y));
    330     }
    331     Vector Normal()
    332     {
    333         double L=sqrt(x*x+y*y);
    334         Vector Vans=Vector(-y/L,x/L);
    335         return Vans;
    336     }
    337 };
    338 
    339 struct polygon
    340 {
    341     int n;      //the number of points
    342     int nl;     //the number of lines
    343     point p[maxp];  //0..n-1
    344     line l[maxp];   //0..nl-1
    345     /*
    346     void input(int X)
    347     {
    348         n=X;
    349         nl=X;
    350         for (int i=0;i<n;i++)
    351         {
    352             p[i].input();
    353         }
    354     }
    355     */
    356     void add(point q)
    357     {
    358         p[n++]=q;
    359     }
    360     /*
    361     void getline()
    362     {
    363         for (int i=0;i<n;i++)
    364         {
    365             l[i]=line(p[i],p[(i+1)%n]);
    366         }
    367     }
    368     */
    369 
    370     //3 点上
    371     //2 边上
    372     //1 内部
    373     //0 外部
    374     int relationpoint(point q)
    375     {
    376         int i,j;
    377         for (i=0;i<n;i++)
    378         {
    379             if (p[i]==q)return 3;
    380         }
    381         //getline();
    382         for (i=0;i<nl;i++)
    383         {
    384             if (l[i].pointonseg(q))return 2;
    385         }
    386         int cnt=0;
    387         for (i=0;i<n;i++)
    388         {
    389             j=(i+1)%n;
    390             int k=dblcmp(q.sub(p[j]).det(p[i].sub(p[j])));
    391             int u=dblcmp(p[i].y-q.y);
    392             int v=dblcmp(p[j].y-q.y);
    393             if (k>0&&u<0&&v>=0)cnt++;
    394             if (k<0&&v<0&&u>=0)cnt--;
    395         }
    396         return cnt!=0;
    397     }
    398 /*
    399     //1 在多边形内长度为正
    400     //2 相交或与边平行
    401     //0 无任何交点
    402     int relationline(line u)
    403     {
    404         int i,j,k=0;
    405         //getline();
    406         for (i=0;i<nl;i++)
    407         {
    408             if (l[i].segcrossseg(u)==2)return 1;
    409             if (l[i].segcrossseg(u)==1)k=1;
    410         }
    411         if (!k)return 0;
    412         vector<point>vp;
    413         for (i=0;i<nl;i++)
    414         {
    415             if (l[i].segcrossseg(u))
    416             {
    417                 if (l[i].parallel(u))
    418                 {
    419                     vp.pb(u.a);
    420                     vp.pb(u.b);
    421                     vp.pb(l[i].a);
    422                     vp.pb(l[i].b);
    423                     continue;
    424                 }
    425                 vp.pb(l[i].crosspoint(u));
    426             }
    427         }
    428         sort(vp.begin(),vp.end());
    429         int sz=vp.size();
    430         for (i=0;i<sz-1;i++)
    431         {
    432             point mid=vp[i].add(vp[i+1]).div(2);
    433             if (relationpoint(mid)==1)return 1;
    434         }
    435         return 2;
    436 */
    437 };
    438 
    439 int k;
    440 double X0,Y0;
    441 line Line[10010];
    442 struct poi
    443 {
    444     int x;  int y;
    445 }a[10010];
    446 
    447 void xsort(int l,int r)
    448 {
    449     int i=l,j=r;
    450     int mid=(l+r)/2;
    451     while(i<j)
    452     {
    453         while((a[i].x<a[mid].x)||((a[i].x==a[mid].x)&&(a[i].y<a[mid].y)))
    454             i++;
    455         while((a[j].x>a[mid].x)||((a[j].x==a[mid].x)&&(a[j].y>a[mid].y)))
    456             j--;
    457         if (i<=j)
    458         {
    459             swap(a[i].x,a[j].x);
    460             swap(a[i].y,a[j].y);
    461             i++;    j--;
    462         }
    463     }
    464     if (l<j)    xsort(l,j);
    465     if (i<r)    xsort(i,r);
    466 }
    467 void ysort(int l,int r)
    468 {
    469     int i=l,j=r;
    470     int mid=(l+r)/2;
    471     while(i<j)
    472     {
    473         while((a[i].y<a[mid].y)||((a[i].y==a[mid].y)&&(a[i].x<a[mid].x)))
    474             i++;
    475         while((a[j].y>a[mid].y)||((a[j].y==a[mid].y)&&(a[j].x>a[mid].x)))
    476             j--;
    477         if (i<=j)
    478         {
    479             swap(a[i].x,a[j].x);
    480             swap(a[i].y,a[j].y);
    481             i++;    j--;
    482         }
    483     }
    484     if (l<j)    ysort(l,j);
    485     if (i<r)    ysort(i,r);
    486 }
    487 
    488 bool cross(point a, point b, point c) {
    489     //if ( ((a.y > c.y && b.y <= c.y) || (a.y <= c.y && b.y > c.y)) && c.x < a.x) {
    490     if ( ( ( (dblcmp(a.y-c.y)==1) && (dblcmp(b.y-c.y)!=1) )||( (dblcmp(a.y-c.y)!=1) && (dblcmp(b.y-c.y)==1) ) ) && (dblcmp(c.x-a.x)==-1) )  {
    491         return true;
    492     }
    493     return false;
    494 }
    495 
    496 int main()
    497 {
    498     while(cin>>k)
    499     {
    500         for (int i=1;i<=k;i++)
    501             cin>>a[i].x>>a[i].y;
    502 
    503         xsort(1,k);
    504         int NL=0;
    505         for (int i=1;i<=k-1;i=i+2)
    506         {
    507             NL++;
    508             Line[NL]=line(point(a[i].x,a[i].y),point(a[i+1].x,a[i+1].y));
    509             //cout<<a[i].x<<","<<a[i].y<<"   "<<a[i+1].x<<","<<a[i+1].y<<endl;
    510         }
    511         ysort(1,k);
    512         for (int i=1;i<=k-1;i=i+2)
    513         {
    514             NL++;
    515             Line[NL]=line(point(a[i].x,a[i].y),point(a[i+1].x,a[i+1].y));
    516             //cout<<a[i].x<<","<<a[i].y<<"   "<<a[i+1].x<<","<<a[i+1].y<<endl;
    517         }
    518 
    519         cin>>X0>>Y0;
    520         point des=point(X0,Y0);
    521         int ans=99,cnt=0;
    522         for (int i=1;i<=NL;i++)
    523         {
    524             line  tl=Line[i];
    525             if (tl.pointonseg(des))
    526             {
    527                 //cout<<i<<endl;
    528                 ans=2;
    529             }
    530             if (cross(tl.a,tl.b,des))
    531             {
    532                 cout<<i<<endl;
    533                 cnt++;
    534             }
    535         }
    536         if (ans==2)
    537             cout<<"BORDER"<<endl;
    538         else
    539         {
    540             if(cnt%2==0)
    541                 cout<<"OUTSIDE"<<endl;
    542             else
    543                 cout<<"INSIDE"<<endl;
    544         }
    545 
    546         /*
    547         PY.n=k;     PY.nl=NL;
    548         for (int i=0;i<k;i++)
    549         {
    550             cout<<a[i+1].x<<","<<a[i+1].y<<endl;
    551             PY.p[i]=point(a[i+1].x,a[i+1].y);
    552         }
    553         for (int i=0;i<NL;i++)
    554         {
    555             cout<<Line[i+1].a.x<<","<<Line[i+1].a.y<<"->"<<Line[i+1].b.x<<","<<Line[i+1].b.y<<endl;
    556             PY.l[i]=Line[i+1];
    557         }
    558 
    559         cin>>X0>>Y0;
    560         int ans=PY.relationpoint(point(X0,Y0));
    561     //3 点上
    562     //2 边上
    563     //1 内部
    564     //0 外部
    565         if (ans==1)
    566             cout<<"INSIDE"<<endl;
    567         else if (ans==0)
    568             cout<<"OUTSIDE"<<endl;
    569         else
    570             cout<<"BORDER"<<endl;
    571         */
    572     }
    573     return 0;
    574 }
    View Code
  • 相关阅读:
    超详细从零记录Hadoop2.7.3完全分布式集群部署过程
    hadoop学习之hadoop完全分布式集群安装
    Fine-tune with Pretrained Models
    Module
    Symbol API
    Gluon parameters 和 Blocks 命名
    mxnet 数据读取
    Adversarial Latent Autoencoders
    A New Meta-Baseline for Few-Shot Learning
    Deploy a plain HTTP registry
  • 原文地址:https://www.cnblogs.com/pdev/p/4470987.html
Copyright © 2020-2023  润新知