原题链接:点击这里
题目描述
假设该湖泊是100乘100平方的湖泊。
假设湖的中心在
(
0
,
0
)
(0,0)
(0,0),而东北角在
(
50
,
50
)
(50,50)
(50,50)。 中心岛是一个以
(
0
,
0
)
(0,0)
(0,0)为中心的圆盘,直径为15。在湖中的不同位置上有许多鳄鱼。 给定每条鳄鱼的坐标和007可以跳跃的距离,您必须告诉他是否可以逃脱。
输入规格:
每个输入文件包含一个测试用例。 每种情况都以包含两个正整数
N
(
≤
100
)
N(≤100)
N(≤100)(鳄鱼的数量)和D(007可以跳跃的最大距离)的行开头。
然后是N行,每行包含一条鳄鱼的
(
x
,
y
)
(x,y)
(x,y)位置。 请注意,没有两个鳄鱼停留在同一位置。
输出规格:
对于每个测试用例,如果007可以逃脱,则打印"Yes",否则打印"No"。
测试1
14 20
25 -15
-25 28
8 49
29 15
-35 -2
5 28
27 -29
-8 -28
-20 -35
-25 -20
-13 29
-30 15
-35 40
12 12
输出Yes
测试2:
4 13
-12 12
12 12
-12 -12
12 -12
输出No
思路:
- 首先对于007,选取每一条鳄鱼所在位置作为节点,首先判断在中心点 ( 0 , 0 ) (0,0) (0,0)的第一跳能跳到的节点有那些 F i r s t J u m p ( i ) 函 数 FirstJump(i)函数 FirstJump(i)函数,对每一个节点做 D F S ( i ) DFS(i) DFS(i)
- 在 D F S DFS DFS中,查找从 i i i节点能达到的下一节点 j j j ( J u m p ( i , j ) 函 数 Jump(i,j)函数 Jump(i,j)函数),同时判断能否到岸 I s s a f e ( i ) 函 数 Issafe(i)函数 Issafe(i)函数
- 因为这里中心岛到第一个跳出的节点的距离 与 之后节点之间的距离的计算公式不一样,要分开对待
- 在判断能否到岸的条件,一定不要马虎。步长D >= 节点到岸边的距离(50-|x| 或 50-|y|)因此还存在一个正负坐标转换的问题,有坑
- 这题还有个值得思考的问题,用什么来保存这个地图的所有节点的坐标呢?这里采用的是结构体数组的方式。非常巧妙。有些时候就是容易钻牛角尖想用邻接矩阵或者邻接表来保存,但其实在此题中,如果这样处理反而变得很麻烦,因此对于图,采用适合的表示方式更好。
参考程序
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=100;
int dfs_vis[maxn];
int N,D;
//用一个结构体数组来保存每个节点的坐标(就是每条鳄鱼所在的坐标)因为鳄鱼最多100条因此定义maxn
struct dex{
int x;
int y;
}Point[maxn];
int Jump(int i,int j)
{
int x1=Point[i].x;
int y1=Point[i].y;
int x2=Point[j].x;
int y2=Point[j].y;
if(D*D>=((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)))
return 1;
else
return 0;
}
int Issafe(int i)
{
int e=Point[i].x;
int f=Point[i].y;
if(e<0)
e=~e+1;
if(f<0)
f=~f+1;
if((D>=50-e) || (D>=50-f))
return 1;
else
return 0;
}
int DFS(int i)
{
dfs_vis[i]=1;
int ans=0;
if(Issafe(i))
{
ans=1;
}
else
{
for(int j=0;j<N;j++)
{
if(dfs_vis[j]==0 && Jump(i,j))
{
ans=DFS(j);
if(ans==1)
break;
}
}
}
return ans;
}
int FirstJump(int i)
{
int a=Point[i].x;
int b=Point[i].y;
if((7.5+D)*(7.5+D)>=(a*a+b*b))
return 1;
else
return 0;
}
void Save007()
{
int answer;
memset(dfs_vis,0,sizeof(0));
for(int i=0;i<N;i++)
{
if(dfs_vis[i]==0 && FirstJump(i))
{
answer=DFS(i);
}
if(answer==1)
break;
}
if(answer==1)
cout << "Yes" <<endl;
else
cout << "No" <<endl;
}
int main()
{
cin >> N >>D;
cin.get();
for(int i=0;i<N;i++)
{
cin >> Point[i].x >> Point[i].y;
cin.get();
}
Save007();
return 0;
}