题目:
一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。
给组测试数据:
INTPUT:
3
S20
111
E20
OUTPUT:
2
INTPUT:
3
S12
345
67E
OUTPUT:
4
#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>
#define N 110
using namespace std;
int vis[N][N], dis[N][N];
int x1, x2, y1, y2, n;
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
char map[N][N];
void bfs(int x, int y)
{
int ans = n * n;
int tx, ty, i, j, k, ttx, tty;
queue<pair<int, int> > Q;
Q.push(make_pair(x, y));
vis[x][y] = 1;
dis[x][y] = 1;
while(!Q.empty())
{
ans--;
if(!ans)
break;
tx = Q.front().first, ty = Q.front().second;
if(tx == x2 && ty == y2)
{
printf("%d\n", dis[x2][y2] - 1);
return ;
}
Q.pop();
if(map[tx][ty] != '1')
{
for(k = 0; k < 4; k++)
{
ttx = tx + dx[k];
tty = ty + dy[k];
if(!dis[ttx][tty] && map[ttx][tty] != '1' && ttx >= 0 && ttx < n && tty >= 0 && tty < n)
{
vis[ttx][tty] = 1;
dis[ttx][tty] = dis[tx][ty] + 1;
Q.push(make_pair(ttx, tty));
if(map[ttx][tty] >= '2' && map[ttx][tty] <= '9')/*注意这应该是一次性的把2~9相同的数字都入队*/
{
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
if(map[i][j] == map[ttx][tty] && !dis[i][j])
{
vis[i][j] = 1;
dis[i][j] = dis[ttx][tty];
Q.push(make_pair(i, j));
}
}
}
}
}
}
printf("Oh No!\n");
}
int main()
{
int i;
while(~scanf("%d", &n))
{
memset(vis, 0, sizeof(vis));
memset(dis, 0, sizeof(dis));
getchar();
for(i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
map[i][j] = getchar();
if(map[i][j] == '1')
vis[i][j] = 1;
else if(map[i][j] == 'S')
x1 = i, y1 = j;
else if(map[i][j] == 'E')
x2 = i, y2 = j;
}
getchar();
}
bfs(x1, y1);
}
return 0;
}