這是一道經典的迷宮問題。
迷宮中有起點、終點、空地(可走)、障礙物(不可走)以及若干傳送點。
從起點開始,到終點結束,每一時刻只能向上、下、左、右四個方向走一步,走一步消耗一單位時間;任意兩個傳送點之間可以互相傳送,且不消耗時間。
你的目標是計算出從起點走到終點的最短時間。
輸入:
第一行包含兩個數字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);
}