回溯—迷宫问题

回溯

数据结构上的例题

要求从迷宫中走出,迷宫如下
0,0,0,0,0,0,0,0,0,0
0,1,1,0,1,1,1,0,1,0
0,1,1,0,1,1,1,0,1,0
0,1,1,1,1,0,0,1,1,0
0,1,0,0,0,1,1,1,1,0
0,1,1,1,0,1,1,1,1,0
0,1,0,1,1,1,0,1,1,0
0,1,0,0,0,1,0,0,1,0
0,0,1,1,1,1,1,1,1,0
0,0,0,0,0,0,0,0,0,0
这里0代表墙,1代表可以走的路。
可以用DFS和BFS写,但是我不会哈哈哈。
下面是代码

#include<iostream>
using namespace std;

#define M 100

#define MAX 0x3f3f3f3f
typedef long long ll;
#define bug(a) cout<<endl<<"*"<<a<<endl;

int arr[10][10] = { 0,0,0,0,0,0,0,0,0,0,//0
				    0,1,1,0,1,1,1,0,1,0,//1
				    0,1,1,0,1,1,1,0,1,0,//2
				    0,1,1,1,1,0,0,1,1,0,//3
				    0,1,0,0,0,1,1,1,1,0,//4
				    0,1,1,1,0,1,1,1,1,0,//5
				    0,1,0,1,1,1,0,1,1,0,//6
				    0,1,0,0,0,1,0,0,1,0,//7
				    0,0,1,1,1,1,1,1,1,0,//8
				    0,0,0,0,0,0,0,0,0,0 };//9
int dic[4][2]={1,0,0,1,-1,0,0,-1};//四个方向移动的坐标
int brr[10][10];
typedef struct node1
{
	int h, l;
}qo;
typedef struct node
{
	int ord;
	qo* seat;//坐标
	qo* base;//底部
	int di;//方向
}stack;
void newstack(stack& s) {
	s.base = new qo[M];//两个都要创空间
	s.seat = new qo[M];//或者s.seat不创空间令s.seat=s.base也行
	if (!s.base) exit(0);
	if (!s.seat) exit(0);
}
void push(stack& s, qo& b) {//将值放入栈里面
	*(s.seat++) = b;
	s.ord++;
}
void pop(stack& s) {//弹出元素,但是不返回值
	if (s.seat == s.base)exit(0);
	s.ord--;
	*(s.seat--);
}
void popp(stack& s, qo& a2) {//弹出元素并且将其带出
	if (s.ord==0)exit(0);
	s.ord--;
	*(s.seat--);
	a2 = *s.seat;
}
int main()
{
	int ans1 = 8,flag=0;//8是因为出口在坐标8,8的位置
	stack s;
	s.ord = 0;//一定要记得给这个标记赋值,不然没输出
	qo a1;
	newstack(s);//创造空间,别忘了
	a1.h = 1;a1.l = 1;
	brr[1][1] = 1;//走过的路标1,开始位置也标记
	push(s, a1);
	while (1) {
		if (a1.h == ans1 && a1.l == ans1) { flag = 1; break; }//有出口令flag=0
		if (s.ord==0)break;//栈为空表示没路到出口,就跳出
		if (arr[a1.h + dic[0][0]][a1.l + dic[0][1]] != 0&&brr[a1.h + dic[0][0]][a1.l + dic[0][1]]==0) {
			a1.h += dic[0][0];
			a1.l += dic[0][1];
			brr[a1.h][a1.l] = 1;
			push(s, a1);
		}
		else {
			int i;
			for (i = 1; i <= 3; i++) {
				if (arr[a1.h + dic[i][0]][a1.l + dic[i][1]] != 0 && brr[a1.h + dic[i][0]][a1.l + dic[i][1]] == 0) {
					a1.h += dic[i][0];
					a1.l += dic[i][1];
					brr[a1.h][a1.l] = 1;
					push(s, a1);
					break;
				}
			}
			if (i > 3) {//这里表示4个方向皆不满足条件,要弹出一个,相当于回溯
				pop(s);
				a1 = *--s.seat;
				*(s.seat++) = a1;//这里表示弹出一个值给a2但是a2再
				brr[a1.h][a1.l] = 1;//给回去相当于没弹出来只是给了他个值
			}
		}
	}
	if (!flag)cout << "eror" << endl;//没路
	else if (flag) {//有路
		qo a2;
		memset(brr, 0, sizeof(brr));//将之前走过的路清0
		int k = s.ord;
		for (int j = 1; j <= k; j++) {
			popp(s, a2);
			brr[a2.h][a2.l] = 1;将直达终点的路标1
		}
		for (int i = 0; i < 10; i++) {
			for (int j = 0; j < 10; j++) {
				if (brr[i][j] == 1)cout << "@" << ' ';//走出去的路被用@标记;
				else cout << "#" << ' ';
			}
			cout << endl;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我已经怒不可遏了!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值