要求
1、 利用栈的迷宫求解
2、 利用队列的迷宫求解
求迷宫路径算法的基本思想
若当前位置“可通”,则纳入路径,继续前进; 若当前位置“不可通”,则后退,换方向继续探索; 若四周“均无通路”,则将当前位置从路径中删除出去。
用栈求迷宫中一条从入口到出口的路径的算法
设定当前位置的初值为入口位置;
do{
若当前没探索过且可通,
则{将当前位置插入栈顶;//纳入路径
若该位置是出口位置,则结束;
//求得路径存放在栈中
否则切换当前位置的东邻方块为新的当前位
置;
}
否则 //当前位置探索过,或不可通
若栈不空且栈顶位置尚有其他方向未被探索,
则设定新的当前位置为: 沿顺时针方向旋转找到的栈顶位置的下一相邻块;
若栈不空但栈顶位置的四周均不可通,
则{删去栈顶位置;// 从路径中删去该通道块
若栈不空,则重新测试新的栈顶位置,
直至找到一个可通的相邻块或出栈至栈空;
}
}while(栈不空)
若栈空,则表明迷宫没有通路。
代码
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
int x;
int y;
}PosType;
typedef struct{
int ord;
PosType seat;
int di;
}SElemType;
typedef struct {
SElemType *base;
SElemType *top;
int stack_size;
}SqStack;
int n;
char mp[100][100];
bool st[100][100];
int go[100][100];
int beside[4][2]={0,1,1,0,-1,0,0,-1};
int ans[1000][2],idx;
SqStack S;
bool InitStack(SqStack u){
u.base = (SElemType*)malloc(1000 * sizeof(SElemType));
if(!u.base) return false;
u.top = u.base;
u.stack_size = 1000;
return true;
}
bool Pass(PosType curpos){
return go[curpos.x][curpos.y]!=4 && mp[curpos.x][curpos.y]!='#'&&st[curpos.x][curpos.y]!=true;
}
bool Push(SqStack *pS,SElemType *pe){
if(pS->top-pS->base >= pS->stack_size){
pS->base = (SElemType*) realloc(S.base,sizeof(SElemType)*(pS->stack_size + 100));
if(!pS->base) return false;
pS->top = pS->base+pS->stack_size;
pS->stack_size = pS->stack_size + 100;
}
st[pe->seat.x][pe->seat.y] = true;
*(pS->top) = *pe;
// printf("push %d %d\n",pS->top->seat.x,pS->top->seat.y);
pS->top++;
return true;
}
void FootPrint(PosType nw){
// printf("(%d,%d)->",nw.x,nw.y);
ans[idx][0]=nw.x;
ans[idx][1]=nw.y;
idx++;
}
PosType NextPos(PosType nw,int stp){
go[nw.x][nw.y] = stp;
PosType res;
res.x=nw.x+beside[stp-1][0];
res.y=nw.y+beside[stp-1][1];
// printf("ne %d %d\n",res.x,res.y);
return res;
}
bool StackEmpty(SqStack u){
if(u.base==u.top) return true;
else return false;
}
bool Pop(SqStack *pS,SElemType *pe){
if(pS->base==pS->top) return false;
pS->top--;
pe->di = pS->top->di;
pe->ord = pS->top->ord;
pe->seat = pS->top->seat;
// printf("pop %d %d\n",pS->top->seat.x,pS->top->seat.y);
return true;
}
void MarkPrint(PosType u){
st[u.x][u.y] = true;
go[u.x][u.y] = 4;
idx--;
}
bool MazePath (PosType start, PosType end){
PosType curpos;
int curstep;
SElemType e;
InitStack (S);
curpos=start;
curstep=1;
int xx=0;
do{
xx++;
if (Pass (curpos)) {
e.ord = curstep;
e.seat = curpos;
e.di = 1;
Push (&S,&e);
if(curpos.x==end.x && curpos.y==end.y) return (true);
FootPrint (curpos);
curpos = NextPos (curpos, 1);
curstep++;
}else{
if (!StackEmpty(S)) {
Pop (&S, &e);
while (e.di==4 && !StackEmpty(S)) {
MarkPrint (e.seat); Pop (&S, &e);
}
if (e.di<4){
e.di++; Push (&S, &e);
curpos = NextPos (e.seat,e.di);
}
}
}
}while (!StackEmpty(S)&&xx<300) ;
return (false);
}
int main(){
scanf("%d",&n);
for(int i=0;i<n;i++) {
scanf("%s", mp[i]);
}
PosType ST={1,1},ED={n-2,n-2};
MazePath(ST,ED);
printf("答案路线:");
for(int i=0;i<idx;i++){
if(i==4) printf("\n");
printf("(%d,%d)->",ans[i][0],ans[i][1]);
}
printf("(%d,%d)",n-2,n-2);
return 0;
}
//##########
//#..#...#.#
//#..#...#.#
//#....##..#
//#.###...##
//#...#...##
//#.#...#..#
//#####.##.#
//#........#
//##########
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
typedef pair<int,int> PII;
char mp[105][105];
PII pre[105][105],go[4]={{0,1},{-1,0},{0,-1},{1,0}};
bool st[105][105];
int n;
void bfs(){
queue<PII> qu;
qu.push({n-2,n-2});
st[n-2][n-2]= true;
while(!qu.empty()){
PII tp=qu.front();
qu.pop();
for(int i=0;i<4;i++){
int x=tp.first+go[i].first;
int y=tp.second+go[i].second;
if(x<0||y<0||x>=n||y>=n||st[x][y]||mp[x][y]=='#') continue;
st[x][y]= true;
pre[x][y]={tp.first,tp.second};
qu.push({x,y});
if(x==1&&y==1) return;
}
}
}
int main(){
cin>>n;
string str;
getchar();
for(int i=0;i<n;i++){
getline(cin,str);
for(int j=0;j<n;j++) mp[i][j]=str[j];
}
bfs();
int x=1,y=1;
while(x!=n-2||y!=n-2){
printf("(%d,%d)->",x,y);
PII t=pre[x][y];
x=t.first,y=t.second;
}
printf("(%d,%d)",n-2,n-2);
return 0;
}