题目
奶牛们去一个N×M玉米迷宫,2≤N≤300,2≤M≤300。
迷宫里有一些传送装置,可以将奶牛从一点到另一点进行瞬间转移。这些装置可以双向使用。
如果一头奶牛处在这个装置的起点或者终点,这头奶牛就必须使用这个装置,奶牛在传送过后不会立刻进行第二次传送,即不会卡在传送装置的起点和终点之间来回传送。
玉米迷宫除了唯一的一个出口都被玉米包围。
迷宫中的每个元素都由以下项目中的一项组成:
- 玉米,
#
表示,这些格子是不可以通过的。 - 草地,
.
表示,可以简单的通过。 - 传送装置,每一对大写字母A到Z表示。
- 出口,
=
表示。 - 起点,
@
表示。
奶牛能在一格草地上可能存在的四个相邻的格子移动,花费1个单位时间。从装置的一个结点到另一个结点不花时间。
输入输出格式
输入格式
第一行:两个用空格隔开的整数N和M。
第2∼N+1行:第i+1行描述了迷宫中的第i行的情况(共有M个字符,每个字符中间没有空格)。
输出格式
一个整数,表示起点到出口所需的最短时间。
输入输出样例
输入样例
5 6
###=##
#.W.##
#.####
#.@W##
######
输出样例
3
代码
#include<iostream>
#include<queue>
using namespace std;
const int N=350;
struct point{
int x,y,t;
};
queue<point> que;
char a[N][N];
bool vis[N][N];
int n,m,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
int sx,sy;
void goto_another(int &nx,int &ny,int k){//传送门
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(a[i][j]==a[nx][ny]&&(i!=nx||j!=ny)){
nx=i;
ny=j;
return;
}
}
}
}
int main(){
cin>>n>>m;
string s;
for(int i=1;i<=n;i++){
cin>>s;
for(int j=1;j<=m;j++){
a[i][j]=s[j-1];
if(a[i][j]=='@'){//找到开头,记录下来
sx=i;
sy=j;
}
}
}
que.push((point){sx,sy,0});
while(!que.empty()){
point f=que.front();
que.pop();
if(a[f.x][f.y]=='='){//找到出口直接输出
cout<<f.t;
return 0;
}
if(a[f.x][f.y]>='A'&&a[f.x][f.y]<='Z'){//找到传送门传送
goto_another(f.x,f.y,f.t);
}
for(int i=0;i<=3;i++){//继续广度优先搜索
int nx=f.x+dx[i];
int ny=f.y+dy[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&a[nx][ny]!='#'&&!vis[nx][ny]){
vis[nx][ny]=true;
que.push((point){nx,ny,f.t+1});
}
}
}
return 0;
}