ZOJ1081 Points Within(射线法判点是否在多边形内)
题目传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=81
【题目大意】
用顶点描述一个多边形,给你几个点(按照顺序给出),对于每个点,如果在多边形内部就输出“Within”,否则输出“Outside”,如果点在边上则视为在内部。
【输入格式】
题目包含多组数据,对于每组数据,先输出“Problem id:”(id表示当前是第几组数据),每组输出之间要有一个换行符。对于每组输入,先给出顶点数N和询问数M,接下来N排,按顺序给出多边形的顶点,接下来M排,给出询问点的坐标。
【输出格式】
对于每次询问,如果点在多边形内,输出"Within",否则输出“Outside”。
【样例输入】
3 1
0 0
0 5
5 0
10 2
3 2
4 4
3 1
1 2
1 3
2 2
0
【样例输出】
Problem 1:
Outside
Problem 2:
Outside
Within
【备注】
N<=100
【题目分析】
好吧我承认我就是照着题解打的。。。。。。。毕竟蒟蒻不会射线法啊QAQ。
射线法实现的细节感觉很多啊,不过感觉没卡。。。。。。。蒟蒻表示难以理解这种情况下射线法的正确性:
望过路大佬解释一下。。。。。。太菜了太菜了QAQ
通过刚才和旁边WCR大佬的交流,发现一个小小的问题,就是下面这一段程序:
point(){}
point(int _x,int _y):x(_x),y(_y){};
可以用这一段程序代替(上面那段不好记啊QAQ,不过=0必须加上,不然定义的时候要打=(0,0))
point(int a=0,int b=0)
{
x=a,y=b;
}
【代码~】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=110;
int n,m;
struct point{
int x,y;
point(){}
point(int _x,int _y):x(_x),y(_y){};
friend inline point operator-(const point &a,const point &b){
return point(b.x-a.x,b.y-a.y);
}
friend inline int operator*(const point &a,const point &b){
return a.x*b.y-a.y*b.x;
}
friend inline int dot(const point &a,const point &b){
return a.x*b.x+a.y*b.y;
}
}q;
bool check(const point &u,const point &v,const point &p)
{
int det=(u-p)*(v-p);
if(det!=0)
return false;
int dott=dot(u-p,v-p);
return dott<=0;
}
struct polygon{
int n;
point p[MAXN];
void init(int _n)
{
n=_n;
for(int i=0;i<n;++i)
scanf("%d%d",&p[i].x,&p[i].y);
p[n]=p[0];
if(Area()<0)
reverse(p,p+n);
p[n]=p[0];
}
int Area()
{
int res=0;
for(int i=0;i<n;++i)
res+=p[i]*p[i+1];
return res;
}
bool inner(const point &q)
{
int cnt=0;
for(int i=0;i<n;++i)
{
if(check(p[i],p[i+1],q))
return true;
int d1=p[i].y-q.y,d2=p[i+1].y-q.y;
int det=(p[i]-q)*(p[i+1]-q);
if((det>=0&&d1<0&&d2>=0)||(det<=0&&d1>=0&&d2<0))
++cnt;
}
return cnt&1;
}
}P;
int main()
{
for(int tt=1;;tt++)
{
scanf("%d",&n);
if(n==0)
break;
scanf("%d",&m);
P.init(n);
if(tt!=1)
puts("");
printf("Problem %d:\n",tt);
while(m--)
{
scanf("%d%d",&q.x,&q.y);
if(P.inner(q))
puts("Within");
else
puts("Outside");
}
}
return 0;
}