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\n",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 }

时间: 2024-10-06 18:38:50

xcoj1062的相关文章