- 1、本文档共9页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
解题思路
这道题要判断多边形?BB?是否被多边形?A?包含,也就是判断?B?中是否有点在?A?的边界上。因此,我们需要求出多边形?A?和?B?的凸包,并比较凸包是否相同。如果凸包相同,就说明?B?在?A?中,否则不在。
对于一个多边形,我们可以用凸包来表示它。凸包是这样一个凸多边形,它的所有顶点都在原来的多边形上,且凸包的每条边都是原来多边形的一条边或者是两条边的延长线的交点。
求解凸包有多种方法,比如Graham扫描算法、Jarvis步进法、Andrew算法等。这里我们采用Graham扫描算法,因为它不需要计算点和线的距离,而且时间复杂度为O(nlogn)。
Graham扫描算法的思路如下:
找到所有点中?y?坐标最小的点p0,如果有多个点的?y?坐标相等,取其中?x?坐标最小的点。
将所有点按照与p0?的极角从小到大排序。如果两个点的极角相同,则按照它们到?p0?的距离从小到大排序。
依次将每个点加入凸包中。如果当前点与前面两个点构成的向量形成的叉积为正,说明当前点在凸包上,否则说明当前点不在凸包上,需要将前面的点弹出。
如果两个多边形的凸包不相同,那么?B?不可能被完全包含在?A?中。因此,如果两个多边形的凸包不相同,直接输出NO即可。
AC_Code
C++
#includebits/stdc++.h
usingnamespacestd;
constdoubleeps=1e-8;
constdoublepi=acos(-1.0);
constintmaxp=2e5;
intsgn(doublex)
{
if(fabs(x)eps)return0;
elsereturnx0?-1:1;
}
structPoint{
doublex,y;
Point(){}
Point(double_x,double_y){
x=_x,y=_y;
}
voidinput()
{
scanf(%lf%lf,x,y);
}
doubledistant(Pointp){
returnhypot(x-p.x,y-p.y);
}
booloperator==(Pointb)const{
returnsgn(x-b.x)==0sgn(y-b.y)==0;
}
booloperator(Pointb)const{
returnsgn(x-b.x)==0?sgn(y-b.y0):xb.x;
}
Pointoperator-(constPointb)const{
returnPoint(x-b.x,y-b.y);
}
//叉积
doubleoperator^(constPointb){
returnx*b.y-y*b.x;
}
Pointoperator+(constPointb)const{
returnPoint(x+b.x,y+b.y);
}
booloperator!=(Pointb)const{
return(*this)==b?0:1;
}
};
structpolygon{
intn;
Pointp[maxp];
voidadd(Pointq){
p[n++]=q;
}
voidinput(int_n){
n=_n;
for(inti=0;in;i++)p[i].input();
}
structcmp{
Pointp;
cmp(constPointp0){p=p0;}
booloperator()(constPointaa,constPointbb){
Pointa=aa,b=bb;
intd=sgn((a-p)^(b-p));
if(d==0){
returnsgn(a.distant(p)
文档评论(0)