回溯
数据结构上的例题
要求从迷宫中走出,迷宫如下
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;
}