题解:P8628 [蓝桥杯 2015 国 AC] 穿越雷区
很板子的广度优先搜索。
题目大意
有一个边长为 \(n\) 的正方形矩阵,里面有 A,B,+,- 这四种字符。A,B 分别表示起点和终点;+,- 分别表示正能量辐射区和负能量辐射区。必须要交替穿过正能量辐射区和负能量辐射区,问最少需要多少步才可以从起点走到终点(起点和终点没有正能量辐射区和负能量辐射区之分,都是安全区)。
题目分析
看到最少就可以明白,这道题目肯定是使用宽度优先搜索来做的。为什么呢?由于宽度优先搜索的性质,我们可以保证第一次到达终点时的方案必定是最优的方案。
接下来,我们还要在广度优先搜索的模板上在添加一些修改。
首先,我们肯定不可以使用直接在原地图上进行修改的方式来标记一个点是否走过。因此我们需要另外开一个数组,来标记一个点是否被走过。
其次,我们还要新添加一个字符来记录这个点走过的字符。这样便于进行判断操作。
接下来,我们就可以开始写代码了。
AC 代码
#include<bits/stdc++.h>
using namespace std;
int n,l,r,ex,ey;
bool vis[105][105];//标记数组
char maz[105][105];//原地图
int dx[5]={0,0,0,-1,1};//方向增量
int dy[5]={0,1,-1,0,0};
struct str{
int x,y,cnt;
char c;
}q[10005];//数组模拟队列
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)//读入+预处理
{
for(int j=1;j<=n;j++)
{
scanf(" %c", &maz[i][j]);
if(maz[i][j]=='A')
{
q[1].x=i;
q[1].y=j;
q[1].cnt=0;
q[1].c=maz[i][j];
vis[i][j]=1;
}
if(maz[i][j]=='B')
{
ex=i;
ey=j;
}
}
}
l=r=1;
while(l<=r)//广度优先搜索
{
for(int i=1;i<=4;i++)//枚举方向
{
int xx=dx[i]+q[l].x;
int yy=dy[i]+q[l].y;
if(xx>0&&xx<=n&&yy>0&&yy<=n&&maz[xx][yy]!=q[l].c&&vis[xx][yy]==0)//判断是否合法
{
vis[xx][yy]=1;
r++;
q[r].x=xx;
q[r].y=yy;
q[r].c=maz[xx][yy];
q[r].cnt=q[l].cnt+1;
}
}
if(q[l].x==ex&&q[l].y==ey)//如果找到了一条路径,那必定是最短路径。直接输出终止程序
{
printf("%d",q[l].cnt);
return 0;
}
l++;
}
printf("-1");//无法到达,输出-1
return 0;
}

浙公网安备 33010602011771号