E. 木头人足球赛 2014新生暑假个人排位赛02
题目描述
木头人星的行动速度是地球上乌龟的 1/10 (所以可以忽略移动的速度),可是他们也热爱运动,尤其是足球。 他们的足球规则跟人类的一样,足球场尺寸为标准 105 * 68,两队各 11 名球员参赛。 假设 Mays 队的每个队员都是专业的球员,踢球都特别准。而她们的对手 Luke 队截球的规律是,如果行进的球离自己的距离不超过 d ,就可以截球成功。 现在 Mays 队的十号球员拿到了球,如果只允许一次射门,Mays 队能不能进球呢? 足球场在 xy 平面内,(0,0)至(105,68)矩形范围内,边缘与 x,y 轴平行且不能站人。其中Luke队的球门为(0, 30)-(0, 38),Mays 队的球门为(105,30)-(105, 38)
输入格式
第一行为组数 T ,对这 T 组数据,每组第一行是Mays队十号球员的坐标 x 0 ,y 0 ,接下来 11 行为 Luke 队的 1 - 11 号队员的属性 x i ,y i ,d i , 其中 x i ,y i 表示 i 号球员的坐标, d i 表示 i 号球员截球能力值。 保证所有坐标不重复且都在球场范围内, x,y 为整数, d 为正实数 1.0≤d≤3.0 。
输出格式
每组数据一行,如果 Mays 队10号队员直接可以射门得分,则输出“Shoot!”;如果10号队员不能成功射门,输出"Poor Mays!".
输入样例
1
104 34
1 24 2.928
48 25 2.605
15 41 1.312
39 42 2.454
3 12 2.080
18 39 1.564
10 36 2.530
97 13 1.589
101 57 1.844
84 39 2.561
0 33 1.831
输出样例
Shoot!
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
//#define LOCAL
using namespace std;
struct point
{
double x,y,d,AngleUp,AngleDown;
}Luke[20];
struct PP
{
double x,y;
}UnCovered[20];
const double eps=1e-7;
const double pi=acos(-1.0);
double xo,yo,AngleUp,AngleDown;
int negativecnt;
bool flag;
bool GetLukeAngle(int x)
{
int i;
double d=sqrt((xo-Luke[x].x)*(xo-Luke[x].x)+(yo-Luke[x].y)*(yo-Luke[x].y));
if(abs(Luke[x].d-d)<eps)return false;
double a=asin(Luke[x].d/d),b;
double dy=Luke[x].y-yo,dx=Luke[x].x-xo;
b=atan2(dy,dx);
if(b>eps)b=3*pi/2-b;
else if(b<-eps)b=-pi/2-b;
else b=pi*3/2;
Luke[x].AngleDown=b-a;
Luke[x].AngleUp=b+a;
return true;
}
bool cmp(const point &a,const point &b)
{
if(abs(a.AngleDown-b.AngleDown)<eps)return a.AngleUp+eps<b.AngleUp;
return a.AngleDown+eps<b.AngleDown;
}
void Init()
{
scanf("%lf%lf",&xo,&yo);
AngleUp=atan2(38.000-yo,-xo);
if(AngleUp<-eps)AngleUp=-AngleUp-pi/2;
else if(AngleUp>eps) AngleUp=pi*3/2-AngleUp;
AngleDown=atan2(30.000-yo,-xo);
if(AngleDown<-eps)AngleDown=-AngleDown-pi/2;
else if(AngleDown>eps) AngleDown=pi*3/2-AngleDown;
flag=true;
for(int i=1;i<=11;i++)
{
scanf("%lf %lf %lf",&Luke[i].x,&Luke[i].y,&Luke[i].d);
if(flag==true)flag=GetLukeAngle(i);
else break;
}
}
void Solve()
{
sort(Luke+1,Luke+1+11,cmp);
flag=false;
double start=AngleDown;
for(int i=1;i<=11;i++)
{
if(Luke[i].AngleUp+eps<AngleDown)continue;
if(Luke[i].AngleDown>AngleUp+eps)continue;
if(Luke[i].AngleDown>start+eps)
{
flag=true;break;
}
else if(Luke[i].AngleUp>start+eps)start=Luke[i].AngleUp;
}
if(flag==false&&start+eps<AngleUp)flag=true;
}
int main()
{
#ifdef LOCAL
freopen("input.txt","r",stdin);
#endif // LOCAL
int T;
scanf("%d",&T);
while(T--)
{
Init();
if(flag==true)Solve();
if(flag)printf("Shoot!\n");
else printf("Poor Mays!\n");
}
return 0;
}