Description

有一个 10 x 10 的迷宫,起点是‘S’,终点是‘E’,墙是‘#’,道路是空格。一个机器人从起点走到终点。当机器人走到一个通道块,前面已经没有路可走时,它会转向到当前面向的右手方向继续走。如果机器人能够过,则留下足迹‘*’,如果走不通,则留下标记‘!’。下面给出书中的算法,请你模拟机器人的走法输出最终的状态。

Input

一个 10 x 10 的二维字符数组。

Output

机器人走过的路径状态。

Sample Input

##########
#S #   # #
#  #   # #
#    ##  #
# ###    #
#   #    #
# #   #  #
# ### ## #
##      E#
##########

Sample Output

##########
#**#!!!# #
# *#!!!# #
#**!!##  #
#*###    #
#***#    #
# #***#  #
# ###*## #
##   ****#
##########

模拟做法(DFS做法在后边)

OK,本题是迷宫的简化版本,不需要找最短路径,不需要找所有路径,只需要按照机器人的行走规则走到终点即可。

首先,我们要分析数据类型的建立。

机器人在行走过程中,我们需要知道的信息有  1,当前位置坐标  2,当前机器人面朝方向。

因此,我们创建数据类型Maze

typedef struct Maze{int x;int y;//坐标 int dir; //面向方向
}Maze;

其次,输入数据是一个二维字符数组,为方便操作,我们将迷宫信息转化成为一个二维数组,我们先约定

方向 : 右 1  下 2   左 3   上 4   (顺时针)

7 代表入口    8 代表出口    5  代表走过的通道块      6  代表走过又退回的通道块

1  代表墙       0  代表可以通过

做完这些,然后我们分析解题思路:

1,读入数据,将其转化为二维数组。

2,获取起点和终点坐标(注意每次给的起点和终点并不一样,所以需要寻找),将起点坐标压栈,进入循环,开始走迷宫

3,每次循环先判断机器人面朝的方向dir,然后判断前方可否通过

1)如果可以通过,将当前坐标数值置为5,然后将下一个要走的坐标压栈,然后将方向重置为1!(每进入一个新的通道 块,都需要朝向1,才能达到寻找所有的方向的效果)!

2)如果不能通过,转向。dir+=1;

方向是1的时候的代码:

if(seat.dir==1){if(a[seat.x][seat.y+1]==0){a[seat.x][seat.y+1]=5;seat.y+=1;seat.dir=1;//每进入一个新的通道块  都需要面朝1 push(&S,seat);continue;}else{seat.dir=seat.dir+1;//转向 continue;}}

3)重点是,方向为4的时候,说明这个通道块前三个方向都不通,如果此时第四个也不通,则弹栈并将该位置置为6,表示走不通。弹栈后,将栈顶坐标方向置为1,然后继续拿来循环

方向为4的代码

if(seat.dir==4){if(a[seat.x-1][seat.y]==0){a[seat.x-1][seat.y]=5;seat.x-=1;seat.dir=1;push(&S,seat);continue;}else{pop(&S,&out);//退栈 a[out.x][out.y]=6;//标记不通 seat.x=( (S.top)-1)->x;seat.y=( (S.top)-1)->y;seat.dir=1;//栈顶坐标方向置为1 continue;}}

4) 每次循环结束后,判断坐标是否等于出口坐标,若等于,说明迷宫结束。

4,将二维数组转化为二维字符数组,打印输出。6对应! 5对应*  1对应#  0对应空格

解题思路可以对照坐标图,自己走一遍循环流程

具体代码如下:

代码中寻找起点终点的操作用的是遍历整个数组,这一点可以优化,有空再改吧。

#include<stdio.h>
#include<string.h>
#include<malloc.h>
typedef struct Maze{int x;int y;//坐标 int dir; //面向方向
}Maze;
typedef struct node{Maze *base;Maze *top;
}Sqtack;
void Input(int a[15][15]);
void Output(int a[15][15]);
void Initstack(Sqtack *L);
int push(Sqtack *S,Maze elem);
int pop(Sqtack *S,Maze *seat);//方向 右1 下2 左3 上4   顺时针
//7代表入口  8代表出口  5代表走过的坐标 6代表走过又退回的坐标
// 1代表墙 0代表可以通过
int main()
{int a[15][15];int Fx,Fy;Input(a);//找到起点 for(int i=0;i<10;i++)for(int j=0;j<10;j++)if(a[i][j]==7){Fx=i;Fy=j;a[i][j]=0;} Sqtack S;Initstack(&S);Maze seat,out;seat.dir=1;seat.x=Fx;seat.y=Fy;a[seat.x][seat.y]=5;push(&S,seat);//找到终点 for(int i=0;i<10;i++)for(int j=0;j<10;j++)if(a[i][j]==8){Fx=i;Fy=j;a[i][j]=0;} while(seat.x!=Fx||seat.y!=Fy){if(seat.dir==1){if(a[seat.x][seat.y+1]==0){a[seat.x][seat.y+1]=5;seat.y+=1;seat.dir=1;//每进入一个新的通道块  都需要面朝1 push(&S,seat);continue;}else{seat.dir=seat.dir+1;//转向 continue;}}if(seat.dir==2){if(a[seat.x+1][seat.y]==0){a[seat.x+1][seat.y]=5;seat.x+=1;seat.dir=1;push(&S,seat);continue;}else{seat.dir=seat.dir+1;//转向 continue;}}if(seat.dir==3){if(a[seat.x][seat.y-1]==0){a[seat.x][seat.y-1]=5;seat.y-=1;seat.dir=1;push(&S,seat);continue;}else{seat.dir=seat.dir+1;//转向continue; }}if(seat.dir==4){if(a[seat.x-1][seat.y]==0){a[seat.x-1][seat.y]=5;seat.x-=1;seat.dir=1;push(&S,seat);continue;}else{pop(&S,&out);//退栈 a[out.x][out.y]=6;//标记不通 seat.x=( (S.top)-1)->x;seat.y=( (S.top)-1)->y;seat.dir=1;//栈顶坐标方向置为1 continue;}}}Output(a);
}
void Input(int a[15][15])//读入数据
{char ch[15];for(int i=0;i<10;i++){gets(ch);int l=strlen(ch);for(int j=0;j<10;j++){if(ch[j]==' '){a[i][j]=0;}if(ch[j]=='#'){a[i][j]=1;}if(ch[j]=='S'){a[i][j]=7;}if(ch[j]=='E'){a[i][j]=8;}}}
}
void Output(int a[15][15])//打印结果
{for(int i=0;i<10;i++){for(int j=0;j<10;j++){if(a[i][j]==1){printf("#");}if(a[i][j]==0){printf(" ");}if(a[i][j]==5){printf("*");}if(a[i][j]==6){printf("!");}}if(i!=9)printf("\n");}
}
void Initstack(Sqtack *S)//初始化
{S->base=(Maze *)malloc(500*sizeof(Maze));S->top=S->base;
}
int push(Sqtack *S,Maze seat)//压栈
{*(S->top)=seat;S->top+=1;
}
int pop(Sqtack *S,Maze *out)//弹栈
{if(S->base==S->top){return -1;}else{S->top-=1;*out=*(S->top);*out=*(S->top);}
}

DFS做法

#include<stdio.h>
int a[20][20];
char s[20][20];
int sx,sy,ex,ey;
int d[4][2]={0,1,1,0,0,-1,-1,0};
int v[20][20];
void intput(){for(int i=0;i<10;i++){for(int j=0;j<10;j++){scanf("%c",&s[i][j]);if(s[i][j]=='#')a[i][j]=1;if(s[i][j]==' ')a[i][j]=0;if(s[i][j]=='S')a[i][j]=7,sx=i,sy=j;if(s[i][j]=='E')a[i][j]=0,ex=i,ey=j;}getchar();}return ;
}
void output(){for(int i=0;i<10;i++){for(int j=0;j<10;j++){if(a[i][j]==1)printf("#");if(a[i][j]==0)printf(" ");if(a[i][j]==7)printf("S");if(a[i][j]==8)printf("E");if(a[i][j]==6)printf("!");if(a[i][j]==5)printf("*");}printf("\n");}return ;
}
void dfs(int x,int y){if(x==ex&&y==ey){a[x][y]=5;output();}v[x][y]=1;a[x][y]=5;for(int i=0;i<4;i++){int xx=x+d[i][0];int yy=y+d[i][1];if(v[xx][yy]==0&&a[xx][yy]==0){dfs(xx,yy);//v[xx][yy]=0;}}a[x][y]=6;return ;
}
int main(){intput();//output();dfs(sx,sy);return 0;
}

迷宫 DFS (模拟和DFS)相关推荐

  1. 736. Lisp 语法解析 : DFS 模拟题

    题目描述 这是 LeetCode 上的 736. Lisp 语法解析 ,难度为 困难. Tag : 「DFS」.「模拟」.「哈希表」 给你一个类似 Lisp 语句的字符串表达式 expression, ...

  2. 历届试题 核桃的数量(3个数的最小公倍数),翻硬币(贪心),买不到的数目(在范围内暴力,找范围,最小公倍数是上界,最小的数是下界),兰顿蚂蚁(dfs,模拟)

    历届试题 核桃的数量 问题描述 小张是软件项目经理,他带领3个开发组.工期紧,今天都在加班呢.为鼓舞士气,小张打算给每个组发一袋核桃(据传言能补脑).他的要求是: 各组的核桃数量必须相同 各组内必须能 ...

  3. 计蒜客:求迷宫解法方案数---dfs

    题目描述: 小信是一个玩迷宫的高手,天下还没有能难住他的迷宫.但是总有人喜欢刁难小信,不停的给小信出难题.这个出题的人很聪敏,他知道天下还没有能难住小信的迷宫.所以他便转换思维问小信,在不走重复路径的 ...

  4. 何时使用hadoop fs、hadoop dfs与hdfs dfs命令

    hadoop fs:使用面最广,可以操作任何文件系统. hadoop dfs与hdfs dfs:只能操作HDFS文件系统相关(包括与Local FS间的操作),前者已经Deprecated,一般使用后 ...

  5. 何时使用hadoop fs、hadoop dfs与hdfs dfs命令(转)

    hadoop fs:使用面最广,可以操作任何文件系统. hadoop dfs与hdfs dfs:只能操作HDFS文件系统相关(包括与Local FS间的操作),前者已经Deprecated,一般使用后 ...

  6. UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP)

    题意:给一个元素周期表的元素符号(114种),再给一个串,问这个串能否有这些元素符号组成(全为小写). 解法1:动态规划 定义:dp[i]表示到 i 这个字符为止,能否有元素周期表里的符号构成. 则有 ...

  7. SDUT 1157-小鼠迷宫问题(BFSamp;DFS)

    SDUT 1157-小鼠迷宫问题(BFS&DFS) 小鼠迷宫问题 Time Limit: 1500ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 小鼠 ...

  8. C++ | 数据结构 | 图结构的讲解与模拟实现 | DFS与BFS的实现

    文章目录 前言 常见概念总结 图的模拟实现 邻接矩阵和邻接表的优劣 图的模拟实现(邻接表) 广度优先遍历(BFS) 深度优先遍历(DFS) hpp代码展示 前言 在聊图的结构之前,我们可以先从熟悉的地 ...

  9. HDU4801 转魔方、DFS模拟

    题目 HDU 4801 给出一个两阶魔方的初始形态,一次可以将一个面转动90° 求在N(1<=N<=7)步内最多能拼成几个面. 题解 由于是两阶魔方,左边UP等于右边DOWN,因此共有6种 ...

  10. 地下迷宫探索 30分 dfs

    地道战是在抗日战争时期,在华北平原上抗日军民利用地道打击日本侵略者的作战方式.地道网是房连房.街连街.村连村的地下工事,如下图所示. 我们在回顾前辈们艰苦卓绝的战争生活的同时,真心钦佩他们的聪明才智. ...

最新文章

  1. 微信小程序(canvas)画图保存到本地相册(wepy)
  2. 人与计算机猜数伪代码,《计算机和算法》PPT课件.ppt
  3. WPF获取鼠标相对于屏幕的绝对位置
  4. git迁移MySQL数据库_Centos7下Gitlab迁移数据库mysql过程
  5. 关于iOS里的做动画方法的差别与注意事项
  6. java pdf打印_Java 打印PDF文档
  7. math.trunc_JavaScript中带有示例的Math.trunc()方法
  8. mysql中char与varchar的区别分析
  9. animate动画案例_animate动画案例——小小购物狂
  10. 启动子级时出错_WHO I级脑膜瘤手术或放射外科治疗后的恶性转变
  11. java跳_用Java实现跳表
  12. Mysql学习总结(73)——MySQL 查询A表存在B表不存在的数据SQL总结
  13. 所有的 iPhone 都已经被破解了!
  14. redis 数据结构笔记
  15. matlab 不确定度计算器,不确定度计算器
  16. vb datagrid mysql_vb ADO 连接数据库,并绑定datagrid控件
  17. python numpy dtype object_python – 创建numpy数组时dtype = object意味着什么?
  18. 信念不熄 热爱当燃|中创算力参加黑客马拉松比赛
  19. 锡兰1.1.0现已上市
  20. 游戏编辑器制作(4)

热门文章

  1. Red Hat Cormier发布OpenShift.io和容器状态指数
  2. Linux stat
  3. UIView属性clipsTobounds的应用
  4. [Linux] sed编辑器
  5. 快速开发框架V0.001(免费、100%开源)
  6. 滴滴自研分布式NoSQL数据库Fusion的演进之路
  7. RESTful API 设计规范
  8. Hadoop I/O
  9. Android ViewPropertyAnimator:让动画变得简单起来!
  10. 从B树、B+树、B*树谈到R树