链接:传送门
题意:给出n个点围成的一个多边形,现在有m个点p,询问p是否在多边形内,你可以认为这些点均不同且输入的顶点是多边形中相邻的两个顶点,最后的顶点与第一个相邻并且每一个顶点都连接两条边( 左右 ),所以这个图形是个简单的多边形。
思路:经典判断点是否在多边形内的题
/*************************************************************************
> File Name: zoj1081.cpp
> Author: WArobot
> Blog: http://www.cnblogs.com/WArobot/
> Created Time: 2017年05月01日 星期一 14时47分03秒
************************************************************************/
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
#define eps 1.0e-5
#define dou double
struct point{
dou x;
dou y;
}po[111];
int n,m;
bool online(point p1,point p,point p2){
if( p.x<=max(p1.x,p2.x) && p.x>=min(p1.x,p2.x) && p.y<=max(p1.y,p2.y) && p.y>=min(p1.y,p2.y) ){
if ( fabs(((p.x-p1.x)*(p2.y-p1.y) - (p.y-p1.y)*(p2.x-p1.x)))<=eps )
return true;
}
return false;
}
bool inside(point p){
int cnt = 0;
dou xinter;
point p1,p2;
p1 = po[0];
for(int i=1;i<=n;i++){
p2 = po[i%n];
if( online(p1,p,p2) ) return true;
if( p.x<=max(p1.x,p2.x) && p.y<=max(p1.y,p2.y) && p.y>min(p1.y,p2.y) ){
if(p1.y!=p2.y){
xinter = (p.y-p1.y)*(p1.x-p2.x)/(p1.y-p2.y) + p1.x; // 理论上的最远距离
if(p1.x==p2.x || p.x<=xinter) cnt++;
}
}
p1 = p2;
}
if(cnt%2==0) return false;
else return true;
}
int main(){
int kase = 0;
point p;
while(~scanf("%d",&n) && n){
scanf("%d",&m);
if(kase) printf("
");
for(int i=0;i<n;i++) scanf("%lf%lf",&po[i].x,&po[i].y);
printf("Problem %d:
",++kase);
for(int i=0;i<m;i++){
scanf("%lf%lf",&p.x,&p.y);
if( inside(p) ) printf("Within
");
else printf("Outside
");
}
}
return 0;
}