回溯求解-迷宫问题

K -

迷宫问题

 

定义一个二维数组: 
int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int map[10][10];
struct node {
	int x[100];// x和y分别用来保存行列坐标 
	int y[100];
	int d;// 用来保存路径的长度,便于找到最短路径 
};
node a[50];//用来保存所有的可能的路径 
int p=0,q;
void lujing()//用来记录路径 
{
	int map2[10][10],i,j;//map2 用来copy地图,因为原来地图不能动,动了原来的地图会导致回溯失败; 
	for(i=0;i<10;i++)
	{
		for(j=0;j<10;j++)
		{
			map2[i][j]=map[i][j];
		}
	}
	i=1,j=1;
	a[p].d=0,q=0;
	while(1)//路径上的点全部被标记为 2 ,然后就从起点开始去记录路径 
	{
		a[p].d++;a[p].x[q]=i,a[p].y[q++]=j;
		if(i==5&&j==5) break;//终点被记录下来就应该退出手动退出死循环 
		if(map2[i][j+1]==2) j++;
		else if(map2[i][j-1]==2) j--;
		else if(map2[i+1][j]==2) i++;
		else if(map2[i-1][j]==2) i--;
		map2[i][j]=0;// 记录过得点就还原(也可以标记为其他的),否则判断下一个点可能还会判断到自己 
	}
	p++;
}
void visit(int i,int j)
{
	map[i][j]=2;
	if(i==5&&j==5)//查找到终点,就应该记录下这条路径 
	{
		lujing();
	}
	if(map[i][j+1]==0) visit(i,j+1);//每到达一个点,按照四个方向查找 
	if(map[i+1][j]==0) visit(i+1,j);
	if(map[i][j-1]==0) visit(i,j-1);
	if(map[i-1][j]==0) visit(i-1,j);
	map[i][j]=0; //查找完一个点就应该退回上一个点,回溯在此! 
}
void init()//将迷宫的周围设置成障碍,减少判断是否超出迷宫的范围 
{
	for(int i=0;i<7;i++)
	{
		map[i][0]=1;
		map[0][i]=1;
		map[i][6]=1;
		map[6][i]=1;
	}
}
int cmp(node x,node y)
{
	return x.d<y.d;
}
int main()
{
	init();
	for(int i=1;i<6;i++)
	{
		for(int j=1;j<6;j++)
		{
			cin>>map[i][j];
		}
	}
	visit(1,1);
	sort(a,a+p,cmp);//按照路径的长短排序 
	for(int i=0;i<a[0].d;i++)
	{
		cout<<"("<<a[0].x[i]-1<<", "<<a[0].y[i]-1<<")"<<endl;
	}
	return 0;
 } 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值