题目描述
小明来到厄运之槌开始单刷,厄运之槌的地图是一个N*M 的矩形,上面遍布了小怪和传送门,其中 1表示有小怪, 0表示无小怪,大写字母表示传送门;
传送门:例如,走到 B 传送门点将传送到另一个B 传送门点(次数无限,但每次进入传送点只传送过去,不会在传送回来);
数据保证每个传送门有且仅有相对应的另一个传送门。
而入口在左上方 (1,1),BOSS却躲在右下方(N,M) 。
小明非常急切的想要完成单刷,所以,小明绝不会在小怪身上浪费时间(当然是绕开他们),并且想通过传送门尽快到达 BOSS 身边。
现在小明找到了你,请求你帮助他。
输入格式
从文件 way.in
中读入数据。
第一行两个数 ;
下面 n 行,每行 m个数(入口点和BOSS点无怪和传送门),表示厄运之槌的地图。
地图数据之间无空格。每步只能走一格,方向上下左右。
左上角为入口点,右下角为出口点。
输出格式
输出到文件 way.out
中。
一个整数,表示小明最少需要走多少步。
如果小明不能走到目标,则输出 “No Solution.”
。
样例
样例输入
3 4
0000
00A0
A000
样例输出
4
样例解释
路线如图:
数据范围与提示
对于60%的数据,1<=n,m<=20;
对于100%的数据,1<=n.m<=100;
【参考程序】
#include <bits/stdc++.h>
using namespace std;
int dir[4][2] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } };
char v[101][101], mapp[101][101];
int n, m, q[20001][2], d[101][101], g[30][4], i, j;
void bfs() { //广搜
int t, x0, y0, x, y, l, r, i;
q[0][0] = q[0][1] = 1;
v[1][1] = 1;
d[1][1] = 0;
for (l = 0, r = 1; l < r; l++) {
x0 = q[l][0];
y0 = q[l][1];
for (i = 0; i < 4; i++) { //四联通
x = x0 + dir[i][0];
y = y0 + dir[i][1];
if (mapp[x][y]) {
t = mapp[x][y];
if (t > 1) {
if (g[t][0] == x && g[t][1] == y) {
x = g[t][2];
y = g[t][3];
} else {
x = g[t][0];
y = g[t][1];
}
}
if (v[x][y]) //判重
continue;
d[x][y] = d[x0][y0] + 1;
q[r][0] = x;
q[r][1] = y;
v[x][y] = 1;
r++;
}
}
}
}
int main() {
freopen("way.in", "r", stdin);
freopen("way.out", "w", stdout);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
scanf("%s", &mapp[i][1]);
for (int j = 1; mapp[i][j] != 0; j++)
if (mapp[i][j] < 60)
mapp[i][j] = 49 - mapp[i][j];
else {
mapp[i][j] -= 63;
int t = mapp[i][j];
if (g[t][0] == 0) {
g[t][0] = i;
g[t][1] = j;
} else {
g[t][2] = i;
g[t][3] = j;
}
}
}
for (i = 1; i <= n; i++)
for (j = 1; j <= m; j++) d[i][j] = 99999;
bfs();
if (d[n][m] == 99999) //不可能走到终点,即依旧是初始化的数据
printf("No Solution.");
else
printf("%d", d[n][m]);
return 0;
}