迷宫问题
文章目录
题目描述:
定义一个二维数组:
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:
Sample Output:
思路分析:
这道题分别可以用DFS和BFS去写,用DFS去写的话,考虑的是栈的问题,由于这次题目只给出了4v4的迷宫,所以不用考虑栈爆的,用BFS不用考虑时间复杂度的问题。
AC代码:
BFS运用了queue结构去写:
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
typedef pair<int, int> P;//定义坐标名称
int c1[5][5];
int m[4][2]={{1,0},{0,1},{-1,0},{0,-1}};//移动方向
int e[5][5];//标记位置
struct num//记录所走的步数与坐标
{
int x;
int y;
int flag;
P Lemon[30];
};
void lemonScanf()//输入迷宫结构
{
int b,c;
for(b=0;b<=4;b++)
{
for(c=0;c<=4;c++)
{
cin >> c1[b][c];
}
}
}
void lemon()
{
int i;
queue<num> d;//创建队列
memset(e, 0, sizeof(e));
num L;//重命,方便操作
L.x=0,L.y=0,L.flag=0;//记录第一步的步数和路径
L.Lemon[L.flag]=P(0, 0);//将第一步的坐标记录
d.push(L);//将L整个结构放进队列中
e[L.x][L.y]=1;//标记
while(d.size())
{
num tema= d.front();//取出第一个元素(这里元素是L)
d.pop();//删除队列中第一个元素
if(tema.x==4 && tema.y==4)
{
for(i=0;i<=tema.flag;i++)
{
cout << '(' << tema.Lemon[i].first <<", "<< tema.Lemon[i].second << ')' << endl;
}
return;
}
for(i=0;i<4;i++)//移动方向以及记录步数,标记所走的位置
{
num Len = tema;
Len.flag++;
Len.x+=m[i][0];
Len.y+=m[i][1];
if(Len.x>=0 && Len.y<=4 && Len.x<=4 && Len.y>=0 && !e[Len.x][Len.y] && c1[Len.x][Len.y]==0)
{//判断是否越界以及该位置能否走
e[Len.x][Len.y]=1;//标记所走的位置
Len.Lemon[Len.flag]=P(Len.x,Len.y);//记录坐标。
d.push(Len);//记录新的元素,将新的结构放进队列
}
}
}
}
int main()
{
lemonScanf();
lemon();
}
BFS不用queue结构:
#include<stdio.h>
#include<string.h>
struct//记录所走的步数与路径
{
int x;
int y;
int sum;
}s[100];
int List[5][5],flag=0,tail=1;
int m[5][2]={{1,0},{0,1},{-1,0},{0,-1}};//移动方向
int h[5][5];//标记是否走过该位置
void LemonPrintf(int g);
void LemonScanf()//输入迷宫构造
{
int b,c;
for(b=0;b<5;b++)
{
for(c=0;c<5;c++)
{
scanf("%d",&List[b][c]);
}
}
}
void LemonBFS()
{
memset(h,0,sizeof(h));
int x1,y1,i;
s[flag].x=0;//记录第一步
s[flag].y=0;
s[flag].sum=-1;
h[0][0]=1;
//
while(flag<tail)// BFS开始
{
for(i=0;i<4;i++)
{
x1=s[flag].x+m[i][0];
y1=s[flag].y+m[i][1];
if(x1>4 || x1<0 || y1>4 || y1<0 || List[x1][y1] || h[x1][y1])
{
continue;
}//判断是否越界 以及是否能走
else//记录路径
{
h[x1][y1]=1;
s[tail].x=x1;
s[tail].y=y1;
s[tail].sum=flag;
tail++;
}
if(x1==4 && y1==4)//到达终点(就是最短的路线)
{
printf("(0, 0)\n");
LemonPrintf(flag);
printf("(4, 4)\n");
}
}
flag++;
}
}
void LemonPrintf(int g)//开始输出路劲
{
if(s[g].sum!=-1)
{
LemonPrintf(s[g].sum);
printf("(%d, %d)\n",s[g].x,s[g].y);
}
// 为什么这样递归能够输出最短路径,步数举个例子:p相当于s[g].sum。
// p[1]=0,p[2]=1, p[3]=2; p[4]=2,p[5]=3,p[6]=4,p[7]=5;
//p[8]=6,p[9]=6, p[10]=7; p[11]=8,p[12]=9,p[13]=10,p[14]=11;
//p[15]=12,p[16]=13;最短路径是从p[16]->p[13]->p[11]->p[8],你就会发现
//其中是递归的规律p[p[n]],相当于这样.
// 为什么这里p[2]与p[3]是相同,递归不会出问题,因为这也是路线所要走的
//步数,所以他们是分开独立的。
}
int main()
{
LemonScanf();//迷宫构造
LemonBFS();//迷宫BFS 找出终点
}
DFS:
#include<stdio.h>
#include<string.h>
int List[5][5];
int L=0,num=0,min,n=0,sum=0;
//num 记录步数
//min 记录最小步数
//n 记录多少条路线到终点
// sum 记录用最少步数的路线到终点。
int h[10][10];//标记是否走过。
struct//记录所走的途径
{
int x[50];
int y[50];
}s[10000];
void LemonPrintf()//输出最短路径
{
int i;
for(i=0;i<min;i++)
{
printf("(%d, %d)\n",s[sum].x[i],s[sum].y[i]);
}
printf("(4, 4)\n");
}
void LemonScanf()//输入迷宫构造
{
int b,c;
for(b=0;b<=4;b++)
{
for(c=0;c<=4;c++)
{
scanf("%d",&List[b][c]);
}
}
}
void LemonDFS(int x1,int y1)
{
if(x1==4 && y1==4)//如果到达终点,记录num(步数)。
{
int i;
if(L==0)//第一次到终点将步数赋于min。
{
min=num;
sum=n;
n++;
L++;
return;
}
for(i=0;i<num;i++)//将前一次所走的路线,赋值于当前所走的路线中。
{
s[n].x[i]=s[n-1].x[i];
s[n].x[i]=s[n-1].y[i];
}
if(min>num)//当后几次到达终点的步数,与min做对比找出最小。
{
sum=n;
min=num;
}
n++;//如果将n++放进去的话会造成WA。
return;
}
if(x1<0 || x1>4 || y1<0 || y1>4)//判断是否越界。
{
return;
}
//向下走
if(List[x1][y1]==0 && h[x1][y1]==0)
{
h[x1][y1]=1;
s[n].x[num]=x1;
s[n].y[num]=y1;
num++;
LemonDFS(x1+1,y1);
num--;
h[x1][y1]=0;
}
//向右走
if(List[x1][y1]==0 && h[x1][y1]==0)
{
h[x1][y1]=1;
s[n].x[num]=x1;
s[n].y[num]=y1;
num++;
LemonDFS(x1,y1+1);
num--;
h[x1][y1]=0;
}
//向上走
if(List[x1][y1]==0 && h[x1][y1]==0)
{
h[x1][y1]=1;
s[n].x[num]=x1;
s[n].y[num]=y1;
num++;
LemonDFS(x1-1,y1);
num--;
h[x1][y1]=0;
}
//
//向左走
if(List[x1][y1]==0 && h[x1][y1]==0)
{
h[x1][y1]=1;
s[n].x[num]=x1;
s[n].y[num]=y1;
num++;
LemonDFS(x1,y1-1);
num--;
h[x1][y1]=0;
}
//
}
int main()
{
memset(h,0,sizeof(h));
LemonScanf();
LemonDFS(0,0);
LemonPrintf();
}