蒟蒻第一次写题解,有什么不对的欢迎私聊。
目录
题目
仙岛求药
少年李逍遥的婶婶病了,王小虎介绍他去一趟仙灵岛,向仙女姐姐要仙丹救婶婶。叛逆但孝顺的李逍遥闯进了仙灵岛,克服了千险万难来到岛的中心,发现仙药摆在了迷阵的深处。迷阵由 M×N 个方格组成,有的方格内有可以瞬秒李逍遥的怪物,而有的方格内则是安全。现在李逍遥想尽快找到仙药,显然他应避开有怪物的方格,并经过最少的方格,而且那里会有神秘人物等待着他。现在要求你来帮助他实现这个目标。
输入格式
第一行输入两个非零整数 M 和 N,两者均不大于 2020。M 表示迷阵行数, N 表示迷阵列数。
接下来有 M 行, 每行包含 N 个字符,不同字符分别代表不同含义:
1) '@':少年李逍遥所在的位置;2) '.':可以安全通行的方格;3) '#':有怪物的方格;4) '*':仙药所在位置。
输出格式
输出一行,该行包含李逍遥找到仙药需要穿过的最少的方格数目(计数包括初始位置的方块)。如果他不可能找到仙药, 则输出 −1−1。
该题我运用了广度优先搜索和队列进行计算,解题思路全写在注释中,内容较简单,更方便食用。
运用队列+pair
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
int m,n,x,y,xx,yy;
char str[30][30];
int arr[30][30]; // 记录从起始位置走到每个坐标的步数
void bfs(int a,int b)
{
queue<pair<int,int>> q; // 创建数对队列 来储存
q.push({x,y}); // 输入李逍遥起始位置的坐标
memset(arr,-1,sizeof(arr));
arr[x][y] = 0; // 表示该位置是起始位置,0表示还没动
int dx[4] = {0,-1,0,1},dy[4] = {1,0,-1,0}; // 确定向那个方向
int flag = 0; // 标记是否找到 *
while(q.size()) // 该处放q.size,目的是当所有位置都不能找到 * ,那么就不会再向q中输入值,那么就结束。
{
pair<int,int> t; // 用来临时储存 q 的值
t = q.front();
q.pop();
for(int i = 0; i < 4; i++) // 4个方向
{
a = t.first+dx[i],b = t.second+dy[i];
// 为了确定不越界和确定可以走的位置和该位置未走过
if(a > 0 && a <= m && b > 0 && b <= n && (str[a][b] == '*'||str[a][b] == '.') && arr[a][b] == -1)
{
q.push({a,b});
arr[a][b] = arr[t.first][t.second]+1; // 记录坐标走的步数
if(str[a][b] == '*') // 找到就结束,节约时间
{
flag = 1;
break;
}
str[a][b] = '#'; // 将已经走过的地方标记一下,防止重复走。
}
}
if(flag == 1) // 找到 * 全部结束
break;
}
}
int main (void)
{
scanf("%d %d",&m,&n);
getchar();
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%c",&str[i][j]);
if(str[i][j] == '@')
x = i,y = j; // 记录李逍遥开始位置
if(str[i][j] == '*')
xx = i,yy = j;// 记录仙药位置
}
getchar(); // 吃掉换行符。
}
bfs(x,y);
if(arr[xx][yy] == -1) // 没有找到过 * 这个点。
printf("-1");
else
{
printf("%d",arr[xx][yy]);
}
return 0;
}
运用队列+结构体
#include<iostream>
#include<queue>
using namespace std;
char map[100][100];
int flag ;
bool used[100][100];
int lix,liy;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
int n,m;
struct node
{
int x,y;
int steps;
}start,nex;
void bfs()
{
used[lix][liy] = true;
queue<node> q;
start.x = lix,start.y = liy,start.steps = 0;
q.push(start);
while(!q.empty())
{
start = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int xx = start.x + dx[i],yy = start.y + dy[i];
if(xx >= 1&&xx<=n && yy>=1&&yy<=m && used[xx][yy] == false&&map[xx][yy] != '#')
{
if(map[xx][yy] == '*')
{
printf("%d",start.steps+1);
flag = 1;
return;
}
used[xx][yy] = true;
nex.x = xx,nex.y = yy,nex.steps = start.steps+1;
q.push(nex);
}
}
}
}
int main (void)
{
cin >> n >> m;
for(int i = 1; i <= n; i++)
{
for(int j = 1;j <= m; j++)
{
cin >> map[i][j];
if(map[i][j] == '@')
{
lix = i;liy = j;
}
}
}
bfs();
if(flag == 0)
printf("-1");
return 0;
}