Cupid's Arrow

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 849    Accepted Submission(s): 306

Problem Description
传说世上有一支丘比特的箭,凡是被这支箭射到的人,就会深深的爱上射箭的人。
世上无数人都曾经梦想得到这支箭。Lele当然也不例外。不过他想,在得到这支箭前,他总得先学会射箭。
日子一天天地过,Lele的箭术也越来越强,渐渐得,他不再满足于去射那圆形的靶子,他开始设计各种各样多边形的靶子。
不过,这样又出现了新的问题,由于长时间地练习射箭,Lele的视力已经高度近视,他现在甚至无法判断他的箭射到了靶子没有。所以他现在只能求助于聪明的Acmers,你能帮帮他嘛?
 
Input
本题目包含多组测试,请处理到文件结束。
在每组测试的第一行,包含一个正整数N(2<N<100),表示靶子的顶点数。
接着N行按顺时针方向给出这N个顶点的x和y坐标(0<x,y<1000)。
然后有一个正整数M,表示Lele射的箭的数目。
接下来M行分别给出Lele射的这些箭的X,Y坐标(0<X,Y<1000)。
 
Output
对于每枝箭,如果Lele射中了靶子,就在一行里面输出"Yes",否则输出"No"。
 
Sample Input
4
10 10
20 10
20 5
10 5
2
15 8
25 8
 
Sample Output
Yes
No
 
Author
linle
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  1700 1757 1755 1798 1147 

 
  计算几何:判断点在多边形内
  开始看这类题算法感觉不难,就是需要考虑的很多,结果自己写模板的时候才发现真心麻烦。WA了好多次,发现是自己想漏了。最后一次提交的时候心情还是很忐忑,不过总算AC了。
  下面是这类题算法的思路,我就是照着下面链接的思路写的模板,具体我就不写在这里了,链接里介绍的很详细:
  我的模板(未优化):
 //判断点q是否在多边形内
//任意凸或者凹多边形
//顶点集合p[]按逆时针或者顺时针顺序存储(1..pointnum)
struct Point{
double x,y;
};
struct Line{
Point p1,p2;
};
double xmulti(Point p1,Point p2,Point p0) //求p1p0和p2p0的叉积,如果大于0,则p1在p2的顺时针方向
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double Max(double a,double b)
{
return a>b?a:b;
}
double Min(double a,double b)
{
return a<b?a:b;
}
bool ponls(Point q,Line l) //判断点q是否在线段l上
{
if(q.x > Max(l.p1.x,l.p2.x) || q.x < Min(l.p1.x,l.p2.x)
|| q.y > Max(l.p1.y,l.p2.y) || q.y < Min(l.p1.y,l.p2.y) )
return false;
if(xmulti(l.p1,l.p2,q)==) //点q不在l的延长线或者反向延长线上,如果叉积再为0,则确定点q在线段l上
return true;
else
return false;
}
bool pinplg(int pointnum,Point p[],Point q)
{
Line s;
int c = ;
for(int i=;i<=pointnum;i++){ //多边形的每条边s
if(i==pointnum)
s.p1 = p[pointnum],s.p2 = p[];
else
s.p1 = p[i],s.p2 = p[i+];
if(ponls(q,s)) //点q在边s上
return true;
if(s.p1.y != s.p2.y){ //s不是水平的
Point t;
t.x = q.x - ,t.y = q.y;
if( (s.p1.y == q.y && s.p1.x <=q.x) || (s.p2.y == q.y && s.p2.x <= q.x) ){ //s的一个端点在L上
int tt;
if(s.p1.y == q.y)
tt = ;
else if(s.p2.y == q.y)
tt = ;
int maxx;
if(s.p1.y > s.p2.y)
maxx = ;
else
maxx = ;
if(tt == maxx) //如果这个端点的纵坐标较大的那个端点
c++;
}
else if(xmulti(s.p1,t,q)*xmulti(s.p2,t,q) <= ){ //L和边s相交
Point lowp,higp;
if(s.p1.y > s.p2.y)
lowp.x = s.p2.x,lowp.y = s.p2.y,higp.x = s.p1.x,higp.y = s.p1.y;
else
lowp.x = s.p1.x,lowp.y = s.p1.y,higp.x = s.p2.x,higp.y = s.p2.y;
if(xmulti(q,higp,lowp)>=)
c++;
}
}
}
if(c%==)
return false;
else
return true;
}

  吉林大学的模板,很精练:

 /*===============================================
| 判断点q是否在多边形内
其中多边形是任意的凸或凹多边形,
Polygon中存放多边形的逆时针顶点序列
================================================*/
int pinplg(int vcount,Lpoint Polygon[],Lpoint q)
{
int c=,i,n;
Llineseg l1,l2;
l1.a=q; l1.b=q; l1.b.x=infinity; n=vcount;
for (i=;i<vcount;i++) {
l2.a=Polygon[i];
l2.b=Polygon[(i+)%n];
if ((lsinterls_A(l1,l2))||
(
(ponls(l1,Polygon[(i+)%n]))&&
(
(!ponls(l1,Polygon[(i+)%n]))&&
(xmulti(Polygon[i],Polygon[(i+)%n],l1.a) *
xmulti(Polygon[(i+)%n],Polygon[(i+)%n],l1.a)>)
||
(ponls(l1,Polygon[(i+)%n]))&&
(xmulti(Polygon[i],Polygon[(i+)%n],l1.a) *
xmulti(Polygon[(i+)%n],Polygon[(i+)%n],l1.a)>)
) ) ) c++;
}
return(c%!=);
}

  题目代码

 #include <iostream>
using namespace std;
//判断点q是否在多边形内
//任意凸或者凹多边形
//顶点集合p[]按逆时针或者顺时针顺序存储(1..pointnum)
struct Point{
double x,y;
};
struct Line{
Point p1,p2;
};
double xmulti(Point p1,Point p2,Point p0) //求p1p0和p2p0的叉积,如果大于0,则p1在p2的顺时针方向
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double Max(double a,double b)
{
return a>b?a:b;
}
double Min(double a,double b)
{
return a<b?a:b;
}
bool ponls(Point q,Line l) //判断点q是否在线段l上
{
if(q.x > Max(l.p1.x,l.p2.x) || q.x < Min(l.p1.x,l.p2.x)
|| q.y > Max(l.p1.y,l.p2.y) || q.y < Min(l.p1.y,l.p2.y) )
return false;
if(xmulti(l.p1,l.p2,q)==) //点q不在l的延长线或者反向延长线上,如果叉积再为0,则确定点q在线段l上
return true;
else
return false;
}
bool pinplg(int pointnum,Point p[],Point q)
{
Line s;
int c = ;
for(int i=;i<=pointnum;i++){ //多边形的每条边s
if(i==pointnum)
s.p1 = p[pointnum],s.p2 = p[];
else
s.p1 = p[i],s.p2 = p[i+];
if(ponls(q,s)) //点q在边s上
return true;
if(s.p1.y != s.p2.y){ //s不是水平的
Point t;
t.x = q.x - ,t.y = q.y;
if( (s.p1.y == q.y && s.p1.x <=q.x) || (s.p2.y == q.y && s.p2.x <= q.x) ){ //s的一个端点在L上
int tt;
if(s.p1.y == q.y)
tt = ;
else if(s.p2.y == q.y)
tt = ;
int maxx;
if(s.p1.y > s.p2.y)
maxx = ;
else
maxx = ;
if(tt == maxx) //如果这个端点的纵坐标较大的那个端点
c++;
}
else if(xmulti(s.p1,t,q)*xmulti(s.p2,t,q) <= ){ //L和边s相交
Point lowp,higp;
if(s.p1.y > s.p2.y)
lowp.x = s.p2.x,lowp.y = s.p2.y,higp.x = s.p1.x,higp.y = s.p1.y;
else
lowp.x = s.p1.x,lowp.y = s.p1.y,higp.x = s.p2.x,higp.y = s.p2.y;
if(xmulti(q,higp,lowp)>=)
c++;
}
}
}
if(c%==)
return false;
else
return true;
}
int main()
{
int N,M;
Point p[];
while(cin>>N){
for(int i=;i<=N;i++)
cin>>p[i].x>>p[i].y;
cin>>M;
while(M--){
Point q;
cin>>q.x>>q.y;
if(pinplg(N,p,q))
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
}
}
return ;
}

Freecode : www.cnblogs.com/yym2013

hdu 1756:Cupid's Arrow(计算几何,判断点在多边形内)的更多相关文章

  1. HDU 1756 Cupid's Arrow 计算几何 判断一个点是否在多边形内

    LINK:Cupid's Arrow 前置函数 atan2 返回一个向量的幅角.范围为[Pi,-Pi) 值得注意的是 返回的是 相对于x轴正半轴的辐角. 而判断一个点是否在一个多边形内 通常有三种方法 ...

  2. HDU 1756 Cupid's Arrow( 判断点在多边形的内外 )

    链接:传送门 思路:判断每支箭是否在多边形内,计算几何点定位中水题,不清楚下面的代码能不能适用于给定点的顺序不确定( 既不是顺时针又不是逆时针 ) /************************* ...

  3. HDU 1756 Cupid's Arrow 判断点在多边形的内部

    Cupid's Arrow Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  4. HDU 1756 Cupid's Arrow (几何问题,判定点在多边形内部)

    题意:中文的么,自己看喽. 析:很容易明白是判定点是不是在多边形内部,一般是向量来判定,我一开始用点在向量的右侧,因为是顺时针给的,只要点全在外侧或边上, 就可以,暴力一下就ok.由于这个是浮点数,一 ...

  5. zoj 1081 判断点在多边形内

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=81Points Within Time Limit: 2 Second ...

  6. 判断点在多边形内算法的C++实现

    目录 1. 算法思路 2. 具体实现 3. 改进空间 1. 算法思路 判断平面内点是否在多边形内有多种算法,其中射线法是其中比较好理解的一种,而且能够支持凹多边形的情况.该算法的思路很简单,就是从目标 ...

  7. php之判断点在多边形内的api

    1.判断点在多边形内的数学思想:以那个点为顶点,作任意单向射线,如果它与多边形交点个数为奇数个,那么那个点在多边形内,相关公式: <?php class AreaApi{ //$area是一个多 ...

  8. POJ 2318 TOYS | 二分+判断点在多边形内

    题意: 给一个矩形的区域(左上角为(x1,y1) 右下角为(x2,y2)),给出n对(u,v)表示(u,y1) 和 (v,y2)构成线段将矩形切割 这样构成了n+1个多边形,再给出m个点,问每个多边形 ...

  9. ZOJ 1081 Points Within | 判断点在多边形内

    题目: 给个n个点的多边形,n个点按顺序给出,给个点m,判断m在不在多边形内部 题解: 网上有两种方法,这里写一种:射线法 大体的思想是:以这个点为端点,做一条平行与x轴的射线(代码中射线指向x轴正方 ...

随机推荐

  1. WebApi2 知识点总结

    1.建议使用异步接口async Task<> public async Task<IHttpActionResult> Get() 如果返回的是IEnumerable请使用: ...

  2. thunder 更改迅雷默认播放器

      更改迅雷的边下边播默认播放器 CreateTime--2017年10月31日08:33:57 Author:Marydon 1.找到迅雷的安装目录,如:D:\SoftWares\PortableE ...

  3. Java中try catch finally的执行顺序问题

    finally 语句块是在 try 或者 catch 中的 return 语句之前执行的.更加一般的说法是,finally 语句块应该是在控制转移语句之前执行,控制转移语句除了 return 外,还有 ...

  4. 理解Load Average做好压力测试(转)

    转载自:http://www.blogjava.net/cenwenchu/archive/2008/06/30/211712.html SIP的第四期结束了,因为控制策略的丰富,早先的的压力测试结果 ...

  5. Mosquitto----服务器日志

    客户端连接日志 1403334375: New connection from 121.201.8.163 on port 1883. 1403334375: New client connected ...

  6. VC版DoEvents

    VB和C#下有一个DoEvents方法,可以让程序在执行操作的同时仍可以处理其他事件.由于近期在做一个数据格式转换的项目,需要进行大批量的数据处理,希望能在进行数据读写过程中,程序还能接收其他操作,防 ...

  7. [elk]Mutate filter plugin增删改查字段

    Mutate filter plugin参考: https://www.elastic.co/guide/en/logstash/current/plugins-filters-mutate.html ...

  8. 用EA生成实体层代码

    在个人版机房重构中.实体层的代码敲得有点儿烦了.不同的实体仅仅是命名不同.代码结构全然一样.遇到反复的事情,就该动动脑.想想办法了. 以下给大家介绍使用EA生成实体层的代码. 首先.建一个类,注意选择 ...

  9. nginx在用户使用ie的使用重定向到/nginx-MSIE目录下

    [root@web01 ]# cat /app/server/nginx/conf/rewrite/default.conf #rewrite ^/index\.html /index.php las ...

  10. javascript的单线程

    1.什么是javascript的单线程javascript是单线程的语言,所以在一个进程上,只能运行一个县城,不能多个线程同时运行.也就是说javascript不允许多个线程共享内存空间.如果多个线程 ...