数据结构(ZKNU OJ)迷宫 DFS方法

Description

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

Input

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

Output

机器人走过的路径状态。

Sample Input

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

Sample Output

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

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

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

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

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

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

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

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

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

1  代表墙       0  代表可以通过

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

扫描二维码关注公众号,回复: 121236 查看本文章

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);
	}
}





猜你喜欢

转载自blog.csdn.net/holly_z_p_f/article/details/79850164