这是一道经典的迷宫问题。
迷宫中有起点、终点、空地(可走)、障碍物(不可走)以及若干传送点。
从起点开始,到终点结束,每一时刻只能向上、下、左、右四个方向走一步,走一步消耗一单位时间;任意两个传送点之间可以互相传送,且不消耗时间。
你的目标是计算出从起点走到终点的最短时间。
输入:
第一行包含两个数字n,m(1<=n,m<=2000)
接下来包含n行,每行m个字符,表示现在的地图。'.'表示空地,'M’表示障碍物,’E’表示传送点,'N'表示起点,'C'表示终点。'N'和’C'在地图中出现且仅出现一次。
输出:
一个数字,表示从起点走到终点的最短时间。如果永远走不到,输出“No Way”。
Sample Input
6 6
...E..
EMM.M.
.M..M.
.MC.M.
.MMM..
N..E..
Sample Output
7
我用的BFS,传送点的话,就第一次碰到传送点就把传送点都入队,当然也可以碰到就入下一个传送点,一个一个入队,反正结果肯定是要都入队,而且每个传送点只入队一次。然后传送点就和这道题没啥关系了。
#include<stdio.h>
#include<string.h>
#define maxn 50000
int n, m,k;//k是多少个传送点
int dx[4] = { 0,0,-1,1 };
int dy[4] = { -1,1,0,0 };
int st[2], ed[2];//起点终点坐标
char map[3000][3000];
int vis[3000][3000];
typedef struct {
int x, y, step;
}NODE;
int chuan[4000000][2];//传送点的坐标
NODE queue[maxn];
int first, end;//用来记录队列的队首队尾位置
int check(int x, int y)
{
if (x >= n || x < 0 || y >= m || y < 0||map[x][y]=='M')
return 0;
if (vis[x][y])
return 0;
return 1;
}
int BFS(int x, int y)
{
int i,j;
first = 0;
end = 0;
NODE now, next;
now.x = x;
now.y = y;
now.step = 0;
vis[now.x][now.y] = 1;
queue[end++] = now;
j=0;
while (first != end)
{
now = queue[first];
if (now.x == ed[0] && now.y == ed[1])
{
return now.step;
}
first++;//q.pop()
if (first >= maxn)//
first = 0;//
if (map[now.x][now.y] == 'E'&&j<k)
{
next.x = chuan[j][0];next.y = chuan[j][1];next.step = now.step ;
if (check(next.x, next.y))
{
vis[next.x][next.y] = 1;
queue[end++] = next;//q.push()
if (end >= maxn)//
end = 0;
}
j++;
}
for (i = 0;i <=3;i++)
{
next.x = now.x + dx[i];
next.y = now.y + dy[i];
next.step = now.step + 1;
if (check(next.x, next.y))
{
vis[next.x][next.y] = 1;
queue[end++] = next;//q.push
if (end >= maxn)//
end = 0;//
}
}
}
return -1;
}
int main()
{
int ans;
int i,j;
scanf("%d%d", &n, &m);
for (i = 0;i < n;i++)
scanf("%s", &map[i]);
k = 0;
for (i = 0;i < n;i++)
for (j = 0;j < m;j++)
{
vis[i][j]=0;
if (map[i][j] == 'N')
{
st[0] = i;st[1] = j;
}
if (map[i][j] == 'C')
{
ed[0] = i;ed[1] = j;
}
if (map[i][j] == 'E')
{
chuan[k][0] = i;chuan[k][1] = j;
k++;
}
}
ans = BFS(st[0],st[1]);
if (ans == -1)
printf("No Way\n");
else printf("%d\n", ans);
}