数据结构图 —— 编程作业 05 :Saving James Bond - Hard Version
Posted 大彤小忆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构图 —— 编程作业 05 :Saving James Bond - Hard Version相关的知识,希望对你有一定的参考价值。
题目描述: 在电影"Live and Let Die"(Live and Let Die)中有一个情节,世界上最著名的间谍007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 他跳到离他最近的鳄鱼的头上,在鳄鱼还没意识到发生了什么之前,又跳到下一个鳄鱼的头上… …最后,他在最后一条鳄鱼咬住他之前上岸,成功逃脱!
假设鳄鱼池是长宽为100米的方形,中心坐标为 (0, 0),且东北角坐标为 (50, 50)。池心岛是以 (0, 0) 为圆心、直径15米的圆。给定池中分布的鳄鱼的坐标、以及007一次能跳跃的最大距离,需要告诉他到达其中一个河岸的最短路径,路径的长度是007必须要跳跃的次数。
输入格式: 每个输入文件包含一个测试用例。
首先第一行给出两个正整数:鳄鱼数量 N(≤100)和007一次能跳跃的最大距离 D。
随后 N 行,每行给出一条鳄鱼的坐标。注意:不会有两条鳄鱼待在同一个点上。
输出格式: 对于每个测试用例,如果007能够逃脱,在一行中输出他必须完成的最小跳跃次数。
然后从下一行开始,在每行中输出从池心岛到岸边的路径上每条鳄鱼的位置(x, y)。
如果007不可能逃跑,则他的跳跃次数为0。
如果有多条最短路径,只输出第一步跳跃距离最短的那条路径,以保证唯一。
输入样例1:
17 15
10 -21
10 21
-40 10
30 -50
20 40
35 10
0 -10
-25 22
40 -40
-30 30
-10 22
0 11
25 21
25 10
10 10
10 35
-30 10
输出样例1:
4
0 11
10 21
10 35
输入样例2:
4 13
-12 12
12 12
-12 -12
12 -12
输出样例2:
0
代码实现:
#include<iostream>
using namespace std;
#include<queue>
#include<stack>
#include<algorithm>
int n, m;
#define MINLEN 42.5
#define MaxVertex 105
struct Pointer { // 存鳄鱼位置信息
int x; // 横坐标
int y; // 纵坐标
}point[MaxVertex];
bool answer = false; // 记录007能否安全逃生
bool visited[MaxVertex] = { false }; // 判断当前点是否被访问过
int path[MaxVertex] = { -1 }; // 记录跳跃过程中踩过的鳄鱼
// 判断从当前点能否跳到岸上
bool isSave(int v)
{
if ((point[v].x - m <= -50) || (point[v].x + m >= 50) || (point[v].y - m <= -50) || (point[v].y + m >= 50))
return true;
return false;
}
// 判断2个点距离是否在跳跃能力内
bool Jump(int v1, int v2)
{
int p1 = pow(point[v1].x - point[v2].x, 2);
int p2 = pow(point[v1].y - point[v2].y, 2);
int r = m * m;
if (p1 + p2 <= r)
return true;
return false;
}
// 当007处于孤岛时,第一次可以选择跳的鳄鱼
int FirstJump(int v)
{
int p1 = pow(point[v].x, 2);
int p2 = pow(point[v].y, 2);
int r = (m + 7.5) * (m + 7.5);
if (p1 + p2 <= r)
{
return p1 + p2;
}
return 0;
}
bool cmp(int a, int b)
{
return FirstJump(a) < FirstJump(b);
}
// 用BFS来判断最少要踩几个鳄鱼才能上岸
void BFS()
{
int b[MaxVertex];
queue<int>q;
// 将第一步能踩到的鳄鱼按距离从小到大的顺序进队列,因为输出结果要保证在踩的鳄鱼数量相等的情况下,输出第一步距离最短的
for (int i = 0; i < n; i++)
b[i] = i;
sort(b, b + n, cmp); // 按照第一步的距离排序
int last;
for (int i = 0; i < n; i++)
{
if (FirstJump(b[i])) // 能跳上去!
{
q.push(b[i]);
visited[b[i]] = true; // 指向当前层数最后一个数
last = b[i];
}
}
int step = 2; // 记录最少要跳跃的次数
int tail = 0;
while (!q.empty())
{
int p = q.front();
q.pop();
if (isSave(p))
{
int k = 1;
stack<int> s;
cout << step << endl;
while (k < step)
{
s.push(p);
p = path[p];
k++;
}
while (!s.empty())
{
p = s.top();
s.pop();
cout << point[p].x << " " << point[p].y << endl;
}
return;
}
for (int i = 0; i < n; i++)
{
if (!visited[i] && Jump(p, i)) // 没踩过并且能跳到
{
q.push(i);
path[i] = p; // 记得当前进队节点的父节点
visited[i] = true;
tail = i; // 指向下一层的最后一个元素
}
}
if (last == p) // 即将进入下一层
{
step += 1;
last = tail;
}
}
if (q.empty()) // 如果队列为空 说明没跳出去
{
cout << "0" << endl;
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i++)
{
cin >> point[i].x >> point[i].y;
}
if (m >= MINLEN) // 可以直接从孤岛上跳到岸上,直接输出
{
cout << "1" << endl;
return 0;
}
BFS();
system("pause");
return 0;
}
测试:
- 测试1:输入样例1的测试效果如下图所示。
- 测试2:输入样例2的测试效果如下图所示。
以上是关于数据结构图 —— 编程作业 05 :Saving James Bond - Hard Version的主要内容,如果未能解决你的问题,请参考以下文章