POJ—3984(迷宫问题)

迷宫问题

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 24793 Accepted: 14481

Description

定义一个二维数组: 

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

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

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

题记:
最近自己在啃数据结构这本书,想要能够自己实现栈、队列、链表等数据结构,希望大三第一学期过后能把课本上的所有数据结构都能自己写出来,现在已经自学(大二浪个里个浪去了
《POJ—3984(迷宫问题)》)到到了第四章(自己太菜,现在要学一点就会一点),不过,最近要把所有看过的自己实现一边才行,活学活用,争取以后非正式比赛都用自己手写实现的栈等数据结构,这个题目是自己从百度上搜出来的,用栈写了一个,但是不是最短路径,所以又用队列写了一个,过几天在用简略版BFS写一遍,加强自己的理解,多多的学习一点基层的东西。
题目分析: 该题目是一个非常经典的路径查找的问题,利用队列存储每一个路径然后将路径输出就可以了。 栈实现路径查找方法(非本题题目要求):

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
struct node{
	int start;
	int end;
	int dis;
};
int main (void)
{
	int i,j;
	int map[10][10];
	//外层制作围墙,方便上下左右移动; 
	for(i=0;i<7;i++)
	   map[i][0] = map[0][i] = 1;
	for(i=0;i<7;i++)
	   map[i][6] = map[6][i] = 1;    
	for(i=1;i<6;i++)
		for(j=1;j<6;j++)
			scanf("%d",&map[i][j]);
	stack<node>st;
	struct node N;
	N.start = 1;
	N.end = 1;
	N.dis = -1;
	//将起点进栈; 
	st.push(N);
	while( !st.empty() ){
		int x,y,D;
		N = st.top() ;
		x = N.start ;
		y = N.end ;
		D = N.dis ;
		map[x][y] = -1;
		//找到目标地点; 
		if(x == 5 && y == 5){
			while(!st.empty() ){
				N = st.top();
				printf("(%d, %d)\n",N.start-1,N.end-1);
				st.pop() ;
			}
			break;
		}
		int find = 0;
		while(D<4 && find == 0)
		{
			D++;
			switch(D){
				case 0 : x = N.start-1; y = N.end;break;
				case 1 : x = N.start; y = N.end+1;break;
				case 2 : x = N.start+1; y = N.end;break;
				case 3 : x = N.start; y = N.end-1;break;
			}
			//标记已经走过,防止陷入死循环; 
			if(map[x][y] == 0) find = 1; 
		}
		//dind == 1表示该点有可以继续走动的下一节点,且进栈下一节点; 
		if(find == 1){
			N.dis = D;
			st.pop() ;
			st.push(N);
			N.start = x;
			N.end = y;
			N.dis = -1;
			st.push(N);
			map[i][j] = -1;  
		}
		//若 find == 0则出栈当前节点; 
		else
		{
			map[N.start][N.end] = 0;
			st.pop() ;
		}
	}	
} 

利用队列实现最短路径: AC code

#include<stdio.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxsize = 10086;
struct box{
	int i,j;
	int pre;
}; 
struct Queue{
	int front;
	int rear;
	box data[maxsize];
};
void print(Queue qu, int front){
	int k = front,j;
	//将路径后缀标记为一,方便查找路径 
	do{
		j = k;
		k = qu.data[k].pre ;
		qu.data[j].pre = -1; 
	}while(k!=0);
	k = 0;
	while(k <= front)
	{
		if(qu.data[k].pre == -1)
		printf("(%d, %d)\n",qu.data[k].i-1,qu.data[k].j-1);
		k++;
	}
}
int main(void){
	int find=0;
	struct Queue qu;
	int map[10][10];
	int i,j;
	for(i=0;i<7;i++)
	   map[i][0] = map[0][i] = 1;
	for(i=0;i<7;i++)
	   map[i][6] = map[6][i] = 1;
	for(i=1;i<6;i++)
	   	for(j=1;j<6;j++)
	   	 	scanf("%d",&map[i][j]);
    qu.rear = -1; 
    qu.front = -1;
    qu.rear++;
    qu.data[qu.rear].i = 1;
    qu.data[qu.rear].j = 1;
	qu.data[qu.rear].pre = -1;
	map[1][1] = -1;
	while(qu.rear != qu.front ){
		qu.front++;
		int x = qu.data[qu.front].i;
		int y = qu.data[qu.front].j;
		if(x == 5 && y == 5)
		{
			print(qu , qu.front);
			break;
		}
		int dis = 0;
		//将所有可走路径进队列 
		for(i=0;i<4;i++)
		{   
			dis++;
			switch(dis)
			{
				case 0 : x =  qu.data[qu.front].i-1 ,y = qu.data[qu.front ].j; break;
				case 1 : x =  qu.data[qu.front].i ,y = qu.data[qu.front ].j+1; break;
				case 2 : x =  qu.data[qu.front].i+1 ,y = qu.data[qu.front ].j; break;
				case 3 : x =  qu.data[qu.front].i ,y = qu.data[qu.front ].j-1; break;
			}
			if(map[x][y] == 0){
				qu.rear++;
				qu.data[qu.rear].i = x;
				qu.data[qu.rear].j = y;
				qu.data[qu.rear].pre = qu.front ;
				//进队元素标记,不走重复路径 
				map[x][y] = -1;
			}
		}
	} 
} 

 

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/xiangkaijie/article/details/78060225
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞