您的位置:首页 > 其它

hiho一下 第六十六周

2015-10-10 15:24 375 查看
题意分析

给定一幅字符表示的地图,其中包含有 1 个起点’H’,若干个座位’S’,墙壁’#’和行人’P’。

其中墙壁’#’和行人’P’是不可通过的区域。

假设在地图中,只能沿着上下左右移动,且每移动一个单元格为 1 步。

询问从’H’点出发,是否能够到达两个相邻的’S’,且需要移动的步数最少是多少。

算法分析

从题目当中,我们就可以知道本题需要做什么:

读取字符地图,并找到起点的位置。

从起点开始,遍历该地图,记录到达每一个'S'的距离。

判断是否有两个相邻的'S'都可达,若存在多个解,则需要找到最小的值。


那么我们就按照这三个步骤来解决这道题目。

首先是数据的读入,由于输入数据中已经明确的告诉了我们地图为 N 行 M 列,所以我们只需要一行一行读入字符串,并使用char map
[M]保存该地图。

map[i][j]表示原地图的第i行第j列的信息。

之后再对整个map[i][j]进行一次 O(mn) 的遍历,找出起点的位置,并记录下来。

我们用startX, startY 来记录起点的坐标。

startX = startY = 0;

// 读入地图

for (int i = 1; i <= N; i++)

scanf(“%s”, map[i] + 1);

// 查找起点H

for (int i = 1; i <= N; i++)

for (int j = 1; j <= M; ++j)

if (map[i][j] == ‘H’) {

startX = i, startY = j;

break;

}

第二步,寻找从起点(startX, startY)分别到每个’S’的最短路径。这一步我们直接使用BFS对整个图进行一次遍历。

首先建立数组int step
[M],step[i][j]表示从起点到(i,j)的最少步数。

初始化为step[i][j] = INT_MAX,默认为任何点都无法到达。

开始遍历时,将step[ startX ][ startY ]设定为0,并以(startX, startY)开始BFS整个地图。

在遍历整个地图的过程中我们需要注意:

当map[i][j] = '#'或map[i][j] = 'P'时,step[i][j]直接等于INT_MAX,并且不扩展新的节点。

当map[i][j] = 'S'时,我们需要更新当前节点的step[i][j]信息,但是由于当小Hi和小Ho走到位置后就不会再进行移动,所以也不扩展新的节点。


最后当没有新的节点可以到达时,退出BFS,得到整个地图的step
[M]。

bool inMap(int x, int y) {

// 在地图内 && 不为墙壁同时也不为行人

return (1 <= x && x <= N && 1 <= y && y <= M) && (map[x][y] == ‘.’ || map[x][y] == ‘S’);

}

const int dir[4][2] = { {0, -1}, {1, 0}, {0, 1}, {-1, 0} }; // 方向数组

vector< pair

#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;

int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
char Map[110][110];
int N, M, step[110][110], rec[110][110];

void BFS(int X, int Y) {
queue <pair <int, int> > q;
q.push(make_pair(X, Y));

while(!q.empty()) {
X = q.front().first;
Y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int x = X + dx[i];
int y = Y + dy[i];
if (x >= 0 && x < N && y >= 0 && y < M && (Map[x][y] == '.' || Map[x][y] == 'S') && !rec[x][y]) {
rec[x][y] = 1;
step[x][y] = step[X][Y] + 1;
if (Map[x][y] == '.') q.push(make_pair(x, y));
}
}
}
}

int main() {
scanf("%d%d", &N, &M);
for (int i = 0; i < N; i++)
scanf("%s", Map[i]);

for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
if (Map[i][j] == 'H') BFS(i, j);

int ans = 0x3f3f3f3f;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++) if (Map[i][j] == 'S' && step[i][j])
for (int k = 0; k < 4; k++) {
int x = i + dx[k];
int y = j + dy[k];
if (x >= 0 && x < N && y >= 0 && y < M && Map[x][y] == 'S' && step[x][y])
ans = min(ans, step[i][j] + step[x][y]);
}

if (ans != 0x3f3f3f3f)
printf("%d\n", ans);
else
puts("Hi and Ho will not have lunch.");

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: