蓝桥杯之穿越雷区 BFS
2018-03-30 23:57
232 查看
本题为2015年第六届蓝桥杯C语言A组试题,第4题。
考点:广度优先搜索(BFS)
广搜一般用来解决“最短”“最少”问题,需用到队列。
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
坦克车只能水平或垂直方向上移动到相邻的区。
数据格式要求:
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。
要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1
例如:
用户输入:
5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
则程序应该输出:
10
资源约定:
峰值内存消耗 < 512M
CPU消耗 < 1000ms
之后找到入口,即“A”所在位置,从该点开始广度优先搜索。
本题解不打算解释为什么BFS能解决此问题,如果想知道,请移步BFS的相关学习文档。本题作为一个典型的BFS题,该题解意在为此类问题提供一个模板。
详细解释看代码:
考点:广度优先搜索(BFS)
广搜一般用来解决“最短”“最少”问题,需用到队列。
题目描述
标题:穿越雷区X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
坦克车只能水平或垂直方向上移动到相邻的区。
数据格式要求:
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。
要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1
例如:
用户输入:
5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
则程序应该输出:
10
资源约定:
峰值内存消耗 < 512M
CPU消耗 < 1000ms
解题思路
用二维数组map[ ][ ]接收“地图”,注意输入时有空格隔开,需要过滤掉空格。之后找到入口,即“A”所在位置,从该点开始广度优先搜索。
本题解不打算解释为什么BFS能解决此问题,如果想知道,请移步BFS的相关学习文档。本题作为一个典型的BFS题,该题解意在为此类问题提供一个模板。
详细解释看代码:
#include<iostream> #include<cstring> #include<queue>//我们使用STL中的队列容器 using namespace std; char map[101][101]; int n; //以下两个数组为坦克走的四个方向 int bx[4]={-1,1,0,0}; int by[4]={0,0,-1,1}; //定义结构体,方便广搜时入队、出队 struct poi{ int x;//记录该点横坐标 int y;//记录该点纵坐标 int step;//记录从起始点走到该点的步数 }; void bfs(int x,int y){ int vis[101][101]={0};//标记某点是否访问过 queue<poi>path;//定义队列path int row,col,step_n;//三个中间变量,对应结构体的三个变量 poi p1;//起始点'A' p1.x=x;//起始点横坐标 p1.y=y;//起始点纵坐标 p1.step=0;//‘A’点的步数肯定是0 path.push(p1);//'A'点入列 vis[x][y]=1;//标记'A'点已访问 while(!path.empty()){//循环遍历,相当于以A为圆心,一圈一圈向四周扩展访问 //以下三行用来访问当前队首元素,依次获取坐标和步数 row=path.front().x; col=path.front().y; step_n=path.front().step; //获取之后,元素出队 path.pop(); for(int i=0;i<4;i++){//向四个方向探索能否走下去 if(row+bx[i]>=n||row+bx[i]<0||col+by[i]>=n||col+by[i]<0) //如果到达边界 continue; if(vis[row+bx[i]][col+by[i]]==0){//要求该点必须未访问过才能进行下列操作 if(map[row][col]!=map[row+bx[i]][col+by[i]]){ //当前该点和接下要走到的点不能相等 //满足以上条件,就可以放心大胆的"走"了 //定义p2,通过p1给它赋值,然后入队,就相当于“走”到了下一点了 poi p2; p2.x=row+bx[i]; p2.y=col+by[i]; p2.step=step_n+1; path.push(p2); vis[p2.x][p2.y]=1; if(map[p2.x][p2.y]=='B'){//判断是否走完 cout<<p2.step<<endl;//走到终点的步数一定是最短的 return; } } } } //如果四个方向都走不通,则说明无路可走,输出-1,直接返回 cout<<-1<<endl; return; } } int main(){ cin>>n; int i,j; char a; for(i=0;i<n;i++){//接收“地图” for(j=0;j<n;j++){ cin>>a; if(a==' '){//注意要忽略空格 --j; continue; } else{ map[i][j]=a; } } } for(i=0;i<n;i++){//用于找到入口'A',因为A不一定在map[0][0]位置 for(j=0;j<n;j++){ if(map[i][j]=='A'){ bfs(i,j); break; } } break; } return 0; }
相关文章推荐
- 第六届蓝桥杯决赛真题 04 穿越雷区(dfs || bfs)
- 蓝桥杯 穿越雷区
- 穿越雷区--bfs宽度优先搜索
- 蓝桥杯java第六届决赛第四题--穿越雷区
- 穿越雷区第六届蓝桥杯大赛个人赛决赛(C语言A组)第四题
- 2015蓝桥杯决赛Java A组 第四题--穿越雷区
- 【蓝桥杯】穿越雷区-java语言描述
- 蓝桥杯 穿越雷区
- 蓝桥杯——穿越雷区
- 第六届蓝桥杯总决赛 穿越雷区
- 2015第七届蓝桥杯决赛C语言A组--穿越雷区(DFS)
- 蓝桥杯 穿越雷区 2015年第六届蓝桥杯JavaB组决赛第四题
- 蓝桥杯--穿越雷区(宽度优先搜索)
- 【蓝桥杯】 穿越雷区
- 第六届蓝桥杯决赛 C语言A组 题解 第四题_穿越雷区
- 蓝桥杯 算法提高 学霸的迷宫 经典BFS问题
- 蓝桥杯 算法提高3000米排名预测(全排列,dfs,bfs)
- 蓝桥杯-学霸的迷宫(BFS+记录操作)
- 穿越泥地(mud) (BFS)
- 蓝桥杯---剪格子(DFS&BFS)(小总结)