数据结构(ZKNU OJ) 迷宫(栈的应用)解题报告
2018-04-08 13:42
399 查看
Description
有一个 10 x 10 的迷宫,起点是‘S’,终点是‘E’,墙是‘#’,道路是空格。一个机器人从起点走到终点。当机器人走到一个通道块,前面已经没有路可走时,它会转向到当前面向的右手方向继续走。如果机器人能够过,则留下足迹‘*’,如果走不通,则留下标记‘!’。下面给出书中的算法,请你模拟机器人的走法输出最终的状态。Input
一个 10 x 10 的二维字符数组。Output
机器人走过的路径状态。Sample Input
########## #S # # # # # # # # ## # # ### # # # # # # # # # ### ## # ## E# ##########
Sample Output
########## #**#!!!# # # *#!!!# # #**!!## # #*### # #***# # # #***# # # ###*## # ## ****# ##########OK,本题是迷宫的简化版本,不需要找最短路径,不需要找所有路径,只需要按照机器人的行走规则走到终点即可。
首先,我们要分析数据类型的建立。
机器人在行走过程中,我们需要知道的信息有 1,当前位置坐标 2,当前机器人面朝方向。
因此,我们创建数据类型Mazetypedef 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);
}
}
相关文章推荐
- Pku acm 1611 The Suspects数据结构题目解题报告(九)---- 并查集的应用
- Pku acm 2492 A Bug's Life数据结构题目解题报告(十)---- 并查集的应用
- 【转】算法基础(二):栈的应用 --- 迷宫解题
- 【解题报告】 HDU 2795 Billboard -- 线段树的应用
- Pku acm 2752 Seek the Name, Seek the Fame数据结构题目解题报告(二十)----kmp算法
- 数据结构应用实例#栈#迷宫寻路
- 2016级数据结构第一次上机解题报告
- Pku acm 2752 Seek the Name, Seek the Fame数据结构题目解题报告(二十)----kmp算法
- Pku acm 1961 Period数据结构题目解题报告(十九)----kmp算法
- 数据结构的应用——使用栈实现任意迷宫的求解
- hdu 1272 小希的迷宫 解题报告
- 17.7.24 校内赛 解题报告【二分答案】【记忆化搜索】【数据结构】
- 迷宫—解题报告
- Pku acm 2406 Power Strings数据结构题目解题报告(十八)----kmp算法
- POJ-3083 Children of the Candy Corn 解题报告(搜索) 广搜深搜走迷宫
- 训练题 极品飞车(并查集应用) 解题报告
- 复习数据结构---纯C编译栈及栈应用(迷宫)
- 【解题报告】 HDU 1272 小希的迷宫 并查集 判连通+判环
- zjnu 1450 - 迷宫(BFS)解题报告
- [CODEVS]数据结构系列 解题报告