kuangbin专题一:K题,POJ3984:迷宫问题(水)
POJ3984:迷宫问题
kuangbin专题一:K题
题目链接:http://poj.org/problem?id=3984
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 24994 | Accepted: 14597 |
Description
定义一个二维数组:
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
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)
思路:最先想到深度优先搜索 并用结构数组存放最优路径
后来想到数组模拟 广度优先搜索
/*Source Code 深度优先搜索实现 Problem: 3984 User: 201616040106 Memory: 208K Time: 0MS Language: C++ Result: Accepted Source Code*/ #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std ; #define maxn 10 bool visit[maxn][maxn] ;//标记 int map[maxn][maxn] ;//地图 struct node { int x ; int y ; }; node result[maxn*10] ; // 存放最优解 结构数组 node path[maxn*10] ;// 当前搜索路径 node starts ; int total ; int dirx[] = {0 , 0 , 1 , -1 } ;// 转向 int diry[] = {1 , -1 , 0 , 0 } ; bool check(int x , int y) { if(x>=0&&x<5&&y>=0&&y<5&&map[x][y]!=1&&!visit[x][y]) return true ; return false ; } void DFS(node Q , int step) { if(step > total) { // 不符合最优解条件 return; } if(Q.x==4&&Q.y==4) { // 找到结果 逐渐修改最优解 if(step < total) { total = step ; for(int i=0 ; i<total ; i++) { result[i] = path[i] ; } } } node turn ; for(int i=0 ; i<4 ; i++) { turn.x = Q.x + dirx[i] ; turn.y = Q.y + diry[i] ; if(check(turn.x , turn.y)) { visit[turn.x][turn.y] = true ;//向前搜索 path[step] = turn ; DFS(turn , step+1) ; visit[turn.x][turn.y] = false ;//回溯 } } return; } int main() { for(int i=0 ; i<5 ; i++) { for(int j=0 ; j<5 ; j++) { scanf("%d" ,&map[i][j]) ; } } memset(visit , false , sizeof(visit)) ; total = 10000000 ; starts.x = 0 ; starts.y = 0 ; DFS(starts , 0 ) ; visit[0][0] = true ; printf("(0, 0)\n") ; for(int i=0 ; i<total ; i++) { printf("(%d, %d)\n" , result[i].x , result[i].y) ; } return 0 ; }
广度优先搜索实现
/*Source Code Problem: 3984 User: 201616040106 Memory: 208K Time: 0MS Language: C++ Result: Accepted Source Code*/ #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std ; #define maxn 10 bool visit[maxn][maxn] ; int map[maxn][maxn] ; int dirx[] = {0 , 0 , -1 , 1 } ; int diry[] = {1 , -1 , 0 , 0 } ; struct node { int x ; int y ; int pre ; // 记录前件 位置 }; node path[maxn*10] ; bool check(node turn ) { if(turn.x>=0 && turn.x<=4 && turn.y>=0 && turn.y<=4) { return true ; } return false ; } void print(int pos) { if(path[pos].pre != -1) { print(path[pos].pre) ; printf("(%d, %d)\n" , path[pos].x , path[pos].y) ; } return; } void BFS() { int Front = 0 ; int head = 1 ; path[Front].x = 0 ; path[Front].y = 0 ; path[Front].pre = -1 ; // 回溯输出终止条件 node turn ; // 数组模拟 BFS 队列操作 并用结构体记录前件 输出时顺序回溯输出 while(Front < head ) { for(int i=0 ; i<=3 ; i++) { turn.x = dirx[i] + path[Front].x ; turn.y = diry[i] + path[Front].y ; turn.pre = Front ; if(check(turn) && !visit[turn.x][turn.y] && map[turn.x][turn.y]!=1) { visit[turn.x][turn.y] = true ; path[head++] = turn ; } } if(path[Front].x == 4 && path[Front].y ==4 ) { printf("(0, 0)\n") ; print(Front) ; break ; } Front++ ; } return; } int main() { while(~scanf("%d" , &map[0][0])) { for(int i=1 ; i<=4 ; i++) { scanf("%d" , &map[0][i]) ; } for(int i=1 ; i<=4 ; i++) { for(int j=0 ; j<=4 ; j++) { scanf("%d" , &map[i][j]) ; } } memset(visit , false , sizeof(visit)) ; BFS() ; } return 0 ; }