XMU C语言程序设计实践(3)

问题描述:

以一个n的长方阵表示迷宫,0和1分别表示迷宫中的通路和障碍,设计一个程序,对任意设定的迷宫,求出一条从入口到出口的通路,或得出没有通路的结论。

对于本问题需用栈实现“穷举求解”算法,即:从入口出发,顺着某一个方向进行探索,若能走通,则继续往前进;否则沿着原路退回,换一个方向继续探索,直至出口位置,求得一条通路。加入所有可能的通路都探索到而未能到达出口,则所设定的迷宫没有通路。迷宫数据是一个n阶矩阵用二维数组存储,起点为(1,1),终点为(n,n),再在迷宫外围加上一层围墙(默认为1,不需用户输入,用户只需输入迷宫数据即可),对于迷宫中每个数据都有四个方向可通。

具体实现算法的函数及要点如下:初始化栈,销毁栈,清空栈,判栈空,取栈顶元素,插入新的栈顶元素,删除栈顶元素,从栈底到栈顶依次访问栈中的每个结点,最重要的就是要判断迷宫的通路。

从迷宫的入口到出口找出一条通路的算法如下:

 

设定当前位置的初值为入口位置;

Do

{

若当前位置可通,

   则

{

将当前位置插入栈顶;

若该位置是出口位置,则算法结束;

                  否则切换当前位置的东邻方块为新的位置;

         }

   否则

{

回到当前位置的前一个位置,判断是否可通(类似于上面算法)

                  ……

    }

}while(栈不空);

若栈不空且栈顶位置尚有其他方向未被探索,

则设定新的当前位置为: 沿顺时针方向旋转

找到的栈顶位置的下一相邻块;

若栈不空但栈顶位置的四周均不可通,

删去栈顶位置;//从路径中删去该通道块

若栈不空,则重新测试新的栈顶位置,

直至找到一个可通的相邻块或出栈至栈空;

若栈空,则表明迷宫通路。

最后根据栈储存的数据输出迷宫径即可。



递归:


//
//by coolxxx
//
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define sqr(a) ((a)*(a))
#define swap(a,b) (a)^=(b),(b)^=(a),(a)^=(b)
#define eps 1e-8
#define MAX 0x7f7f7f7f
#define N 1004
#define M 1000004
char map[N][N];
int u[N][N];
int n,m,ans,lll;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int a[M][2];
void pop()
{
	a[lll][0]=a[lll][1]=0;
	lll--;
}
void push(int x,int y)
{
	a[++lll][0]=x;
	a[lll][1]=y;
}
void gettop(int *x,int *y)
{
	*x=a[lll][0];
	*y=a[lll][1];
}
int uempty()
{
	return lll;
}
void init()
{
	int i;
	memset(a,0,sizeof(a));
	memset(u,0,sizeof(u));
	lll=0;
}
int dfs(int x,int y)
{
	if(x==n && y==n && map[x][y]=='0')
		return 1;
	int i,j,xx,yy;
	u[x][y]=1;
	for(i=0;i<4;i++)
	{
		xx=x+dx[i];
		yy=y+dy[i];
		if(xx<1 || yy<1 || xx>n || yy>n || map[xx][yy]=='1' || u[xx][yy])continue;
		j=dfs(xx,yy);
		if(j)
		{
			push(xx,yy);
			return 1;
		}
	}
	return 0;
}
int main()
{
//	freopen("1.txt","r",stdin);
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%s",map[i]+1);
		puts(map[i]+1);
	}
	if(map[1][1]=='1'){puts("No way");return 0;}
	init();
	if(dfs(1,1))
	{
		push(1,1);
		for(i=lll;i>1;i--)
			printf("(%d,%d)->",a[i][0],a[i][1]);
		printf("(%d,%d)\n",n,n);
	}
	else
	{
		puts("No way");
	}
	return 0;
}
/*

*/


非递归:


//
//by coolxxx
//
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(a) ((a)>0?(a):(-(a)))
#define sqr(a) ((a)*(a))
#define swap(a,b) (a)^=(b),(b)^=(a),(a)^=(b)
#define eps 1e-8
#define MAX 0x7f7f7f7f
#define N 1004
#define M 1000004
char map[N][N];
int u[N][N];
int n,m,ans,lll;
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
int a[M][2];
void pop()
{
	a[lll][0]=a[lll][1]=0;
	lll--;
}
void push(int x,int y)
{
	a[++lll][0]=x;
	a[lll][1]=y;
}
void gettop(int *x,int *y)
{
	*x=a[lll][0];
	*y=a[lll][1];
}
int uempty()
{
	return lll;
}
void init()
{
	int i;
	memset(a,0,sizeof(a));
	memset(u,0,sizeof(u));
	lll=0;
}
void print()
{
	int i,j;
	for(i=1;i<lll;i++)
		printf("(%d,%d)->",a[i][0],a[i][1]);
	printf("(%d,%d)\n",n,n);
}
void dfs()
{
	int i,j,x,y,xx,yy;
	gettop(&x,&y);
	if(x==n && y==n && map[x][y]=='0')
	{
		print();
		exit(0);
	}
	for(i=0;i<4;i++)
	{
		xx=x+dx[i];
		yy=y+dy[i];
		if(xx<1 || yy<1 || xx>n || yy>n || map[xx][yy]=='1' || u[xx][yy])continue;
		push(xx,yy);
		u[xx][yy]=1;
		dfs();
		pop(xx,yy);
	}
}
int main()
{
//	freopen("1.txt","r",stdin);
	int i,j;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%s",map[i]+1);
		puts(map[i]+1);
	}
	if(map[1][1]=='1'){puts("No way");return 0;}
	push(1,1);
	dfs(1,1);
	puts("No way");
	return 0;
}
/*

*/




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值