再遇攻击
Time Limit: 1000 MS Memory Limit: 65536 K
Total Submit: 253(37 users) Total Accepted: 56(29 users) Rating: Special Judge: No
Description
Dota中英雄技能攻击会有一个范围,现在释放一个技能给出他的攻击范围和目标英雄的位置,问是否能攻击到。攻击范围保证是一个多边型。
Input
有多组测试数据
第一行输入1个整数n, 期中n代表攻击范围是给出的n个点组成的多边形,按照时针方向(顺或逆)依次给出,(n>=3)N = 0输入结束。
第二行a,b表示目标英雄的坐标( 0 < a,b<100)
接下来有n行,每行两个整数x,y(0 < x,y <100)表示每个点的坐标
攻击范围在边缘也算在内
Output
每组结果输出占一行
如果能够攻击到输出”Yes”
否则输出”No”
Sample Input
3
1 1
4 4
5 4
4 6
0
Sample Output
No
Author
鲁学涛
计算几何,判断点是否在多边形内。
水题,没有什么需要注意的地方。
代码:
1 #include <stdio.h>
2 struct Point{ 3 double x,y; 4 }; 5 struct Line{ 6 Point p1,p2; 7 }; 8 double xmulti(Point p1,Point p2,Point p0) //求p1p0和p2p0的叉积,如果大于0,则p1在p2的顺时针方向
9 { 10 return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); 11 } 12 double Max(double a,double b) 13 { 14 return a>b?a:b; 15 } 16 double Min(double a,double b) 17 { 18 return a<b?a:b; 19 } 20 bool ponls(Point q,Line l) //判断点q是否在线段l上
21 { 22 if(q.x > Max(l.p1.x,l.p2.x) || q.x < Min(l.p1.x,l.p2.x) 23 || q.y > Max(l.p1.y,l.p2.y) || q.y < Min(l.p1.y,l.p2.y) ) 24 return false; 25 if(xmulti(l.p1,l.p2,q)==0) //点q不在l的延长线或者反向延长线上,如果叉积再为0,则确定点q在线段l上
26 return true; 27 else
28 return false; 29 } 30 bool pinplg(int pointnum,Point p[],Point q) 31 { 32 Line s; 33 int c = 0; 34 for(int i=1;i<=pointnum;i++){ //多边形的每条边s
35 if(i==pointnum) 36 s.p1 = p[pointnum],s.p2 = p[1]; 37 else
38 s.p1 = p[i],s.p2 = p[i+1]; 39 if(ponls(q,s)) //点q在边s上
40 return true; 41 if(s.p1.y != s.p2.y){ //s不是水平的
42 Point t; 43 t.x = q.x - 1,t.y = q.y; 44 if( (s.p1.y == q.y && s.p1.x <=q.x) || (s.p2.y == q.y && s.p2.x <= q.x) ){ //s的一个端点在L上
45 int tt; 46 if(s.p1.y == q.y) 47 tt = 1; 48 else if(s.p2.y == q.y) 49 tt = 2; 50 int maxx; 51 if(s.p1.y > s.p2.y) 52 maxx = 1; 53 else
54 maxx = 2; 55 if(tt == maxx) //如果这个端点的纵坐标较大的那个端点
56 c++; 57 } 58 else if(xmulti(s.p1,t,q)*xmulti(s.p2,t,q) <= 0){ //L和边s相交
59 Point lowp,higp; 60 if(s.p1.y > s.p2.y) 61 lowp.x = s.p2.x,lowp.y = s.p2.y,higp.x = s.p1.x,higp.y = s.p1.y; 62 else
63 lowp.x = s.p1.x,lowp.y = s.p1.y,higp.x = s.p2.x,higp.y = s.p2.y; 64 if(xmulti(q,higp,lowp)>=0) 65 c++; 66 } 67 } 68 } 69 if(c%2==0) 70 return false; 71 else
72 return true; 73 } 74 int main() 75 { 76 int i,n; 77 while(scanf("%d",&n)!=EOF){ 78 if(n==0) break; 79 Point t; 80 scanf("%lf%lf",&t.x,&t.y); 81 Point p[101]; 82 for(i=1;i<=n;i++) //输入多边形的顶点
83 scanf("%lf%lf",&p[i].x,&p[i].y); 84 if(pinplg(n,p,t)) 85 printf("Yes\n"); 86 else
87 printf("No\n"); 88 } 89 return 0; 90 }
Freecode : www.cnblogs.com/yym2013