阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫。
今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔吉侬最喜欢的奶酪。
现在研究员们想知道,如果阿尔吉侬足够聪明,它最少需要多少时间就能吃到奶酪。
迷宫用一个 R×C 的字符矩阵来表示。
字符 S 表示阿尔吉侬所在的位置,字符 E 表示奶酪所在的位置,字符 # 表示墙壁,字符 . 表示可以通行。
阿尔吉侬在 1 个单位时间内可以从当前的位置走到它上下左右四个方向上的任意一个位置,但不能走出地图边界。
输入格式
第一行是一个正整数 T,表示一共有 T 组数据。
每一组数据的第一行包含了两个用空格分开的正整数 R 和 C,表示地图是一个 R×C 的矩阵。
接下来的 R 行描述了地图的具体内容,每一行包含了 C 个字符。字符含义如题目描述中所述。保证有且仅有一个 S 和 E。
输出格式
对于每一组数据,输出阿尔吉侬吃到奶酪的最少单位时间。
若阿尔吉侬无法吃到奶酪,则输出“oop!”(只输出引号里面的内容,不输出引号)。
每组数据的输出结果占一行。
数据范围
1
输入样例:
3
3 4
.S…
###.
…E.
3 4
.S…
.E…
…
3 4
.S…
…E.
输出样例:
5
1
oop!
BFS(利用队列来实现)
如果有解一定会找出路径
找出的路径一定是最小的,
常见模板:
queue -------------初始状态
while(queue.size()) -------------当队列不空时
{
auto t=q,fornt
q.pop(队头出队列)
for() ------------------遍历新的元素
{
if*(没有出现过!!!!!通常是memset(cnt,-1,sizeof cnt)初始化为-1)
q.push()------ 插入新的结点
}
}
#include
#include
#include
#include
#include
using namespace std;
typedef pair<int,int>PII;
const int N=210;
int T;
int r,c;
char s[N][N];
int dist[N][N];
int bfs(PII start,PII end){
queue<PII>q;
memset(dist, -1, sizeof dist);
dist[start.first][start.second]=0;
q.push(start);
int dx[4]={
0,0 ,1,-1};
int dy[4]={
1,-1,0, 0};
while(q.size()){
auto t=q.front();
q.pop();
for(int i=0;i<4;i++){
int x1=dx[i]+t.first;
int y1=dy[i]+t.second;
if(s[x1][y1]=='#'){
continue;} //遇到墙
if(x1<0 || x1>=r || y1<0 || y1>=c){
continue; } // 出界;
if(dist[x1][y1]!=-1){
continue;} //被访问过;
dist[x1][y1]=dist[t.first][t.second]+1;
if (end.first==x1 && end.second==y1) return dist[x1][y1];
q.push( {
x1,y1} );
}
}
return -1;
}
int main(){
PII start,end;
cin>>T;
while(T--){
scanf("%d%d",&r,&c);
for(int i=0;i<r;i++){
scanf("%s",s[i]);
}
for(int i=0;i<r;i++){
for(int j=0;j<c;j++){
if(s[i][j]=='S'){
start={
i,j};
}
if(s[i][j]=='E'){
end={
i,j};
}
}
}
int distance=bfs(start,end);
if(distance==-1) puts("oop!");
else{
cout<<distance<<endl;}
}
return 0;
}
使用结构体定义queue数组的方法
#include
#include
#include
#include
using namespace std;
struct P{
int x, y;
};
const int N = 210;
int n, m;
char g[N][N];
int dist[N][N];
P q[N*N*N];
int bfs(P start, P end)
{
int hh=0,tt=0;
q[0]=start;
memset(dist, -1, sizeof dist);
dist[start.x][start.y] = 0;
int dx[4] = {
-1, 0, 1, 0}, dy[4] = {
0, 1, 0, -1};
while (hh<=tt)
{
auto t = q[hh++];
for (int i = 0; i < 4; i ++ )
{
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= m) continue; // 出界
if (g[x][y] == '#') continue; // 障碍物
if (dist[x][y] != -1) continue; // 之前已经遍历过
dist[x][y] = dist[t.x][t.y] + 1;
if (end.x==x && end.y==y) return dist[x][y];
q[++tt]={
x,y};
}
}
return -1;
}
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
P start, end;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
if (g[i][j] == 'S') start = {
i, j};
else if (g[i][j] == 'E') end = {
i, j};
int distance = bfs(start, end);
if (distance == -1) puts("oop!");
else printf("%d\n", distance);
}
return 0;
}