迷宫问题
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)
题记:
最近自己在啃数据结构这本书,想要能够自己实现栈、队列、链表等数据结构,希望大三第一学期过后能把课本上的所有数据结构都能自己写出来,现在已经自学(大二浪个里个浪去了
)到到了第四章(自己太菜,现在要学一点就会一点),不过,最近要把所有看过的自己实现一边才行,活学活用,争取以后非正式比赛都用自己手写实现的栈等数据结构,这个题目是自己从百度上搜出来的,用栈写了一个,但是不是最短路径,所以又用队列写了一个,过几天在用简略版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;
}
}
}
}