迷宫问题(回溯法)

问题:

给定一个入口,一个出口,找出从入口到出口的所有路径。

图例:

其中: // 代表墙    入口:(1,1) 出口:(7,8)

分析:

1. 中间格子有4种走法:东、南、西、北

2. 但对于两边的格子,只有两种走法,为了普遍性,给其上下左右各加一行格子,作为墙。如图:红色区域。

3. 走过的路需要标记,要不然会出现死循环,前一个格子走到下一个格子,而下一个格子其余三边都是墙,如果不标记判断,就会走回去,然后出现死循环现象。标记为1.

4. 贪心选择的顺序:<向出口方向走>

即:在Move数组中存储四个方位的增量

5. 每次按照固定的走法试探时,选择不是墙,且没有标记的格子走。

解法:

遍历四叉树

代码:

# include <stdio.h>
// 全局变量 
int M[9][10];	// 迷宫地图 
int Move[4][2]; 	// 试探顺序:南、东、北、西 
int cnt = 0;		// 计数器 
int tip = 1;		// 计算总可能数 

// 函数声明
void Maze(int x, int y); 
void ChuShiHua();
void ChuMove();
void print();

int main (void){	
	// 初始化棋盘
	ChuShiHua();
	// 初始化顺序表
	ChuMove();	
	
	print();

	// 调用函数 
	M[1][1] = 1;
	Maze(1,1);
	
	
	return 0;
} 

// 初始化迷宫 
void ChuShiHua(){
	int i,j;
	/*新加的最左最右列墙*/ 
	for(i = 0; i <= 8; i++){
		M[i][0] = -1;		// -1代表墙 
		M[i][9] = -1;		
	}
	/*新加的最上最下列墙*/
	for (j = 0; j <= 9; j++) {
		M[0][j] = -1;
		M[8][j] = -1; 
	} 
	/*设置内部的墙*/
	M[1][1] = 0;
	M[1][2] = 0;
	M[1][3] = -1;
	M[1][4] = -1;
	M[1][5] = -1;
	M[1][6] = -1;
	M[1][7] = -1;
	M[1][8] = -1;
	M[2][1] = 0;
	M[2][2] = 0;
	M[2][3] = 0;
	M[2][4] = -1;
	M[2][5] = -1;
	M[2][6] = -1;
	M[2][7] = -1;
	M[2][8] = -1;
	M[3][1] = -1;
	M[3][2] = 0;
	M[3][3] = 0;
	M[3][4] = 0;
	M[3][5] = 0;
	M[3][6] = 0;
	M[3][7] = -1;
	M[3][8] = -1;
	M[4][1] = -1;
	M[4][2] = -1;
	M[4][3] = 0;
	M[4][4] = 0;
	M[4][6] = 0;
	M[4][5] = -1;
	M[4][7] = -1;
	M[4][8] = 0;
	M[5][1] = -1;
	M[5][2] = -1;
	M[5][3] = -1;
	M[5][4] = 0;
	M[5][5] = -1;
	M[5][6] = 0;
	M[5][7] = 0;
	M[5][8] = 0;
	M[6][1] = -1;
	M[6][2] = -1;
	M[6][3] = -1;
	M[6][4] = 0;
	M[6][5] = 0;
	M[6][6] = 0;
	M[6][7] = -1;
	M[6][8] = 0;
	M[7][1] = -1;
	M[7][2] = -1;
	M[7][3] = -1;
	M[7][4] = -1;
	M[7][5] = -1;
	M[7][6] = 0;
	M[7][7] = 0;
	M[7][8] = 0;
} 

// 输出所有可能的解 
void Maze(int x, int y){
	// 结束 
	if (x == 7 && y == 8){
		print();	// 输出棋盘 
		return;
	}
	// 没有结束,就往下走 
	int i;
	for (i = 0; i < 4; i++) {		// 有4中选择 
		int a = x + Move[i][0];		// 计算下一步位置 
		int b = y + Move[i][1];
		if (M[a][b] == 0){			// 能走 
			M[a][b] = 1;
			Maze(a,b);
			M[a][b] = 0;
		}
	}
}

// 初始化顺序表
void ChuMove(){
	Move[0][0] = 1;		Move[0][1] = 0;
	Move[1][0] = 0;		Move[1][1] = 1;
	Move[2][0] = -1;	Move[2][1] = 0;
	Move[3][0] = 0;		Move[3][1] = -1;
} 

void print(){
	int i,j;
	printf("\n\n第%d个:\n",tip++); 
	for(i = 0; i <= 8; i++) {
		for (j = 0; j <= 9; j++) {
			printf(" %2d ",M[i][j]);
		}
		printf("\n");
	} 
}

输入输出展示:

无输入

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值