【蓝桥第三周】老鼠走迷宫
2015-12-19 16:18
281 查看
老鼠走迷宫
问题描述
老鼠走迷宫是递回求解的基本题型,
试以程式求出由入口至出口的路径,入口为左上角,出口为右下角。
迷宫图7×7
墙的表示:█ 路径的表示:◇
INPUT
(无)
OUTPUT
显示迷宫:
显示路径:
解法一
[解题思路]
深度搜索,在题的基础上考虑了多种路径到达终点的状况,输出最短路径,需要注意的是a[index].ans[new_x][new_y]=0;
[代码实现]
[解题思路]
广度优先搜索,找最短路径。利用队列实现。
[代码实现]
问题描述
老鼠走迷宫是递回求解的基本题型,
试以程式求出由入口至出口的路径,入口为左上角,出口为右下角。
迷宫图7×7
墙的表示:█ 路径的表示:◇
INPUT
(无)
OUTPUT
显示迷宫:
显示路径:
解法一
[解题思路]
深度搜索,在题的基础上考虑了多种路径到达终点的状况,输出最短路径,需要注意的是a[index].ans[new_x][new_y]=0;
[代码实现]
#include<iostream> using namespace std; const int N=7; /* 地图,1表示障碍 0表示可用 */ int Map ={ 1,1,1,1,1,1,1, 1,0,0,0,0,1,1, 1,0,1,1,1,0,1, 1,0,1,0,0,0,1, 1,0,1,0,1,0,1, 1,0,0,0,1,0,1, 1,1,1,1,1,1,1 }; int book ; /* 标记 */ /* 为了找出最短路径 */ struct node { int step; /* 所用步数 */ int ans ; /* 一种路径 */ }a[100]; int index=0,min_index; /* 最少步数的下标 */ int Min=9999; /* 最小步数 */ const int end_x=5,end_y=5; /* 终点 */ /* 方向 */ int Next[4][2] = {{0, 1},{1, 0},{0, -1},{-1, 0}};/*右,下,左,上*/ void dfs(int x,int y,int Step) { a[index].ans[1][1]=2; /* 起点标记 */ if(x==end_x && y==end_y) { a[index].step=Step; /* 保存步数 */ if(Step<Min) { Min=Step; /* 更新 min step */ min_index=index; /* 只要输出最小步数的路径,所以记录下来 */ } index++; return ; } for(int i=0;i<=3;i++) { int new_x=x+Next[i][0]; int new_y=y+Next[i][1]; if(new_x<1 || new_x>N-1 ||new_y<1 ||new_y>N-1) /* 越界 */ { continue; } if(book[new_x][new_y]==0 && Map[new_x][new_y]!=1) /* 没有使用过,并且没有障碍*/ { book[new_x][new_y]=1; a[index].ans[new_x][new_y]=2; dfs(new_x,new_y,Step+1); a[index].ans[new_x][new_y]=0; book[new_x][new_y]=0; } } } void print() { for(int i=0;i<N;i++) for(int j=0;j<N;j++) { if(Map[i][j]==0) { if(a[min_index].ans[i][j]==2)cout<<"◇"; else cout<<" "; } else cout<<"█"; if(j==N-1) cout<<endl; /* 格式控制 */ } cout<<endl; } int main() { print(); dfs(1,1,0); print(); return 0; }解法二
[解题思路]
广度优先搜索,找最短路径。利用队列实现。
[代码实现]
#include<iostream> using namespace std; struct note { int x; //横坐标 int y; //纵坐标 int f; //父亲在队列中的编号 int s; //步数 }que[100]; const int N=8; int Book ={0}; //标记是否已经扩展 //迷宫初始化 int Map ={ 0,0,0,0,0,0,0,0, 0,1,1,1,1,1,1,1, 0,1,0,0,0,0,1,1, 0,1,0,1,1,1,0,1, 0,1,0,1,0,0,0,1, 0,1,0,1,0,1,0,1, 0,1,0,0,0,1,0,1, 0,1,1,1,1,1,1,1 }; //定义一个用于表示走的方向的数组 int Next[4][2] = { {0, 1}, //右 {1, 0}, //下 {0, -1}, //左 {-1, 0} }; //上 int head=1;int tail=1; //队列初始化 void pfs(int start_x,int start_y,int end_x,int end_y); void print(int start_x,int start_y); int main() { int start_x,start_y; //开始位置 int end_x,end_y; //目标位置 start_x=2;start_y=2; //起点初始化 end_x=6;end_y=6; //终点初始化 pfs(start_x,start_y,end_x,end_y); //广度 print(start_x,start_y); //显示 return 0; } void pfs(int start_x,int start_y,int end_x,int end_y) { int new_x,new_y; //扩展的x,y //往队列插入迷宫入口坐标 que[tail].x=start_x; que[tail].y=start_y; que[tail].f=0; que[tail].s=0; tail++; Book[start_x][start_y]=1; int flag=0; //用来标记是否到达目标点,0表示暂时还没有到达,1表示到达 //队列不为空循环 while(head<tail) { //枚举4个方向 for(int i=0;i<4;i++) { //计算下一个点的坐标 new_x=que[head].x+Next[i][0]; new_y=que[head].y+Next[i][1]; //判断是否越界 if(new_x<1 || new_x>N-1 || new_y<1 || new_y>N-1) { continue; } //判断是否是障碍物或者已经在路径中 if(Book[new_x][new_y]==0 && Map[new_x][new_y]==0) { //把这个点标记为已经走过 //注意宽搜每个点只入队一次,所以和深搜不同,不需要将Book还原 Book[new_x][new_y]=1; que[tail].x=new_x; que[tail].y=new_y; que[tail].f=head; //因为这个点是从head扩展出来的,所以它的父亲是head que[tail].s=que[head].s+1; //步数是父亲的步数+1 tail++; } if(new_x==end_x && new_y==end_y) { flag=1; break; } }//for循环结束 if(flag==1) { break; } head++; }//while循环结束 } void print(int start_x,int start_y) { //打印队列中末尾最后一个点(目标点)的步数 //注意tail是指向队尾(即最后一位)的下一个位置,所以这需要-1 //printf("%d",que[tail-1].s); int temp=tail-1; //将路径标为2用于输出 while(1) { Map[que[temp].x][que[temp].y]=2; temp=que[temp].f; if(que[temp].x==start_x && que[temp].y==start_y) //当父亲结点是起点时候结束 { Map[que[temp].x][que[temp].y]=2; break; } } //打印迷宫 for(int i=1;i<N;i++) { for(int j=1;j<N;j++) { if(Map[i][j]==1) { cout<<"█"; } if(Map[i][j]!=1) { cout<<" "; } } cout<<endl; } //打印路径 for(int i=1;i<N;i++) { for(int j=1;j<N;j++) { if(Map[i][j]==1) { cout<<"█"; } if(Map[i][j]==2) { cout<<"◇"; } if(Map[i][j]==0) { cout<<" "; } } cout<<endl; } }
相关文章推荐
- BZOJ1192鬼谷子的钱袋
- 一条ssh命令实现端口转发,实现跨机器直接访问
- Struts2加载自定义库注意事项
- 初识ACM——这都是啥-.-
- 树莓派摄像头设备找不到/dev/video0的解决方法
- STL_7:空间配置器
- jquery mobile 移动web(3)
- AutoLayout处理UITableView动态高度
- Java集合框架简述
- VS2010动态库生成及应用问题
- Objective-C NSValue类的常用方法
- 联想在钛媒体峰会上提前泄漏了MOTO新杀器
- linux内核-锁机制
- CSingleLock::CSingleLock https://msdn.microsoft.com/zh-cn/library/fw63hszf.aspx
- 重新编译spark 增加spark-sql适配CDH
- 下拉列表 简单代码
- [BZOJ1007]水平可见直线
- Arduino - IIC SCANNER
- 【iOS学习笔记 15-12-19】自定义cell侧滑按钮(UIButton)
- 性能测试知多少----性能测试分类之我见