问题 F: 【递归入门】走迷宫
时间限制: 1 Sec 内存限制: 128 MB
提交: 128 解决: 46

题目描述
  有一个n*m格的迷宫(表示有n行、m列),其中有可走的也有不可走的,如果用1表示可以走,0表示不可以走,文件读入这n*m个数据和起始点、结束点(起始点和结束点都是用两个数据来描述的,分别表示这个点的行号和列号)。现在要你编程找出所有可行的道路,要求所走的路中没有重复的点,走时只能是上下左右四个方向。如果一条路都不可行,则输出相应信息(用-l表示无路)。
  请统一用 左上右下的顺序拓展,也就是 (0,-1),(-1,0),(0,1),(1,0)

输入
第一行是两个数n,m( 1 < n , m < 15 ),接下来是m行n列由1和0组成的数据,最后两行是起始点和结束点。

输出
  所有可行的路径,描述一个点时用(x,y)的形式,除开始点外,其他的都要用“->”表示方向。
  如果没有一条可行的路则输出-1。

样例输入
5 6
1 0 0 1 0 1
1 1 1 1 1 1
0 0 1 1 1 0
1 1 1 1 1 0
1 1 1 0 1 1
1 1
5 6

样例输出
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(3,4)->(4,4)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(2,4)->(2,5)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(3,4)->(3,5)->(4,5)->(5,5)->(5,6)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)->(4,4)->(4,5)->(5,5)->(5,6)

提示
【算法分析】
  用一个a数组来存放迷宫可走的情况,另外用一个数组b来存放哪些点走过了。每个点用两个数字来描述,一个表示行号,另一个表示列号。对于某一个点(x,y),四个可能走的方向的点描述如下表:
   2

1  x,y  3

   4
  对应的位置为:(x, y-1),(x-1, y),(x, y+1),(x+1, y)。所以每个点都要试探四个方向,如果没有走过(数组b相应的点的值为0)且可以走(数组a相应点的值为1)同时不越界,就走过去,再看有没有到达终点,到了终点则输出所走的路,否则继续走下去。

这个查找过程用search来描述如下:

procedure search(x, y, b, p);{x,y表示某一个点,b是已经过的点的情况,p是已走过的路}

 begin
   for i:=1 to 4 do{分别对4个点进行试探}
   begin
     先记住当前点的位置,已走过的情况和走过的路;
     
     如果第i个点(xl,y1)可以走,则走过去;

     如果已达终点,则输出所走的路径并置有路可走的信息,

     否则继续从新的点往下查找search(xl,y1,b1,p1);
   end;
 end;
  有些情况很明显是无解的,如从起点到终点的矩形中有一行或一列都是为0的,明显道路不通,对于这种情况要很快地“剪掉”多余分枝得出结论,这就是搜索里所说的“剪枝”。从起点开始往下的一层层的结点,看起来如同树枝一样,对于其中的“枯枝”——明显无用的节点可以先行“剪掉”,从而提高搜索速度。

经验总结
这题有坑!!上面加粗的那一句话,就是坑人的,这题不需要提示中所谓的剪枝,如果真这么剪枝了,那就没法做对了,原因如下:
如果输入数据:
4 4
0 1 0 0
0 1 0 0
0 1 0 1
0 1 1 1
1 2
3 4
从起点(1,2)到终点(3,4)的矩形为:
1 0 0
1 0 0
1 0 1
很明显,有一列为0,但是,这个迷宫无解吗?
并不是,(1,2)->(2,2)->(3,2)->(4,2)->(4,3)->(4,4)->(3,4)即为唯一解。
所以,请不要加提示所说的剪枝,除此之外,注意无解输出-1的特判,其他的问题就不大啦~~
总结完毕 (ฅ´ω`ฅ)
emmmm经过前几个程序的历练,写非递归不是那么头疼啦!开心!!
非递归提升的方法,就是要自己写,千万别看别人的代码,一点点的总结,才能逐渐的进步♪(^∀^●)ノ

递归代码

#include <cstdio>
using namespace std;
int m,n,last_x,last_y,start_x,start_y;
int atlas[20][20];
bool flag[20][20]={false};
int direct[4][2]={{0,-1},{-1,0},{0,1},{1,0}};
int index,count;
int answer[250][2];
bool judge(int x,int y)
{if(x==0||y==0||y>n||x>m)return false;if(atlas[x][y]==0||flag[x][y]==true)return false;return true;
}
void dispose(int x,int y,int index)
{if(x==last_x&&y==last_y){for(int i=0;i<index;i++){if(i!=index-1)printf("(%d,%d)->",answer[i][0],answer[i][1]);elseprintf("(%d,%d)\n",answer[i][0],answer[i][1]);}count++;return ;}for(int i=0;i<4;i++){int new_x=x+direct[i][0];int new_y=y+direct[i][1];if(judge(new_x,new_y)){flag[new_x][new_y]=true;answer[index][0]=new_x;answer[index][1]=new_y;dispose(new_x,new_y,index+1);flag[new_x][new_y]=false;}}
}
int main()
{while(~scanf("%d %d",&m,&n)){for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){scanf("%d",&atlas[i][j]);flag[i][j]=false;}}scanf("%d %d",&start_x,&start_y);scanf("%d %d",&last_x,&last_y);index=0;count=0;if(judge(start_x,start_y)){flag[start_x][start_y]=true;answer[index][0]=start_x;answer[index][1]=start_y;dispose(start_x,start_y,index+1);if(count==0){printf("-1\n");}}else{printf("-1\n");}}return 0;
}

非递归代码

#include <cstdio>
#include <stack>
using namespace std;int m,n,last_x,last_y,start_x,start_y;
int atlas[20][20];
bool flag[20][20]={false};
bool tflag[20][20][4]={false};
int direct[4][2]={{0,-1},{-1,0},{0,1},{1,0}};
int count;
int answer[250][2];
struct node
{int number,x,y,type;
};
bool judge(int x,int y)
{if(x==0||y==0||y>n||x>m)return false;if(atlas[x][y]==0||flag[x][y]==true)return false;return true;
}
void dispose()
{stack<node *> process;bool pflag=false;node *p=new node();p->number=0;p->x=start_x;p->y=start_y;p->type=0;flag[start_x][start_y]=true;answer[p->number][0]=start_x;answer[p->number][1]=start_y;process.push(p);while(!process.empty()){node *top=process.top();if(top->x==last_x&&top->y==last_y){for(int i=0;i<=top->number;i++){if(i==top->number){printf("(%d,%d)\n",answer[i][0],answer[i][1]);}else{printf("(%d,%d)->",answer[i][0],answer[i][1]);}}count++;pflag=true;}if(pflag==true){flag[top->x][top->y]=false;for(int i=0;i<4;i++)tflag[top->x][top->y][i]=false;process.pop();pflag=false;continue;}int f=0;for(int i=0;i<4;i++){int new_x=top->x+direct[i][0];int new_y=top->y+direct[i][1];if(judge(new_x,new_y)&&tflag[top->x][top->y][i]==false){tflag[top->x][top->y][i]=true;node *temp=new node();temp->number=top->number+1;temp->x=new_x;temp->y=new_y;temp->type=i;flag[new_x][new_y]=true;answer[temp->number][0]=new_x;answer[temp->number][1]=new_y;process.push(temp);f=1;break;}}if(f==0){pflag=true;}}
}
int main()
{while(~scanf("%d %d",&m,&n)){for(int i=1;i<=m;i++){for(int j=1;j<=n;j++){scanf("%d",&atlas[i][j]);flag[i][j]=false;for(int k=0;k<4;k++)tflag[i][j][k]=false;}}scanf("%d %d",&start_x,&start_y);scanf("%d %d",&last_x,&last_y);count=0;if(judge(start_x,start_y)){dispose();if(count==0){printf("-1\n");}}else{printf("-1\n");}}return 0;
}

5978 Problem F 【递归入门】走迷宫相关推荐

  1. java递归老鼠走迷宫_递归算法求老鼠走迷宫(C语言)

    /*说明老鼠走迷宫是递回求解的基本题型,我们在二维阵列中使用2表示迷宫墙壁, 使用1来表示老鼠的行走路径,试以程式求出由入口至出口的路径. 解法老鼠的走法有上.左.下.右四个方向,在每前进一格之后就选 ...

  2. java递归老鼠走迷宫_老鼠走迷宫----------递归问题

    老鼠走迷宫是一个典型的递归的问题,写几个这样的题才可以充分理解递归的过程. 写递归的过程有几点需要注意: (1)递归结束的条件 (2)递归过程的脉络,即逻辑要清晰. / // // 在迷宫中显示老鼠能 ...

  3. 算法实验三 Problem F木乃伊迷宫

    Problem F 木乃伊迷宫 时限:1000ms 内存限制:10000K 总时限:3000ms 描述: 木乃伊地下宫殿是一个6行6列的迷宫.作为敢到木乃伊地下宫殿里去探险的你,有没有跟木乃伊抓迷藏的 ...

  4. 迷宫python_Python走迷宫,递归 - nixBlog

    递归走迷宫,练手. 23下午就写好的,可是测试几种不同的迷宫后,发现有个Bug,我以为算法有问题,今早才发现,原来是isDest函数里r和c都写成r了,拷贝out函数的语句再改写造成的悲剧. #!/u ...

  5. DFS(入门题,走迷宫)

    1185: 走迷宫 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 383 Solved: 155 [Submit][Status][Web Board] ...

  6. Java递归解决老鼠走迷宫问题

    思路 1 表示障碍 代码 public class MiGong{public static void main(String[] args){int[][] map = new int[8][7]; ...

  7. 递归走迷宫java,java递归实现的迷宫游戏

    java递归实现的迷宫游戏 public class Migong { private int gard[][]={  {1,1,1,1,0,1,1,1}, {0,0,0,1,1,1,1,1}, {1 ...

  8. java走迷宫_走迷宫问题Java递归

    public class MazeDemo { /* 走迷宫,1代表墙,从左上角的0走到右下角的0,找到一条通路,若存在,返回true,若不存在,返回false 1 1 1 1 1 1 1 1 0 0 ...

  9. 华为OD机试 - 机器人走迷宫(Python)| 递归的使用

    OD统一考试B卷:机器人走迷宫 题目 房间有 X*Y 的方格组成,例如下图为6*4的大小.每一个放个以坐标(x,y)描述. 机器人固定从方格(0,0)出发,只能向东或者向北前进, 出口固定为房间的最东 ...

最新文章

  1. 登上Science子刊,神经科学再次启发DNN设计!中科院揭秘介观自组织反向传播机制...
  2. python浪漫代码-python爱心表白 每天都是浪漫七夕!
  3. 虚拟IO服务器,虚拟IO服务器VIOS概念.doc
  4. Hash Length Extension Attacks
  5. 抛硬币直到连续若干次正面
  6. php里的抽象类和接口
  7. javascript 的参数有长度限制吗?一个细节引起的误区
  8. @Scheduled cron表达式详解
  9. t–sql pl–sql_SQL Server性能疑难解答的DBA指南–第2部分–监视实用程序
  10. java c 传递字符串数组_JNI传递字符串数组J-StringArray
  11. 有关PyCharm的破解安装
  12. Excel中如何往上/往下全选(Mac)
  13. blender导出html,神器,C4D互导插件,可与Maya和Blender模型快速复制粘贴导出脚本Quick CopyPaste (Blender, Maya, C4D)...
  14. 基于Spring Boot的讲师积分管理系统(毕业设计,毕设)
  15. EXCEL慢的解决方法
  16. nuxt如何添加背景图片
  17. 微软的MSR paraphrase数据集
  18. 单片机流水灯全亮c语言程序,终极流水灯单片机C语言程序.doc
  19. 《Python数据分析与挖掘实战》第7章-聚类+绘制雷达图
  20. 07 面向对象编程-结构、封装、继承、多态、接口

热门文章

  1. 尚硅谷阳哥SpringCloud第二季学习笔记(一)
  2. 基于东北F4的设计模式情景剧——第一幕 装饰模式(Decorator Pattern)
  3. JS实现把表格数据导出,并生成为excel下载到本地
  4. 知名新能源充电桩企业采购我司标签视觉识别系统
  5. PHP绘制圣诞树 圣诞树(油画效果)
  6. 初探机器学习之使用百度EasyDL定制化模型
  7. Ubuntu 下如何把安装好的软件图标放置在桌面左侧
  8. JavaScript运行错误求助
  9. 食品安全企业标准备案
  10. 《无人驾驶车辆模型预测控制》之车辆运动学模型