POJ-3824-迷宫问题

迷宫问题

题目描述:

定义一个二维数组:

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();
}
发布了49 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/xiaosuC/article/details/104147311