您的位置:首页 > 其它

经典递归问题--走迷宫--POJ 3984

2014-04-11 13:53 281 查看

迷宫问题

Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 6937Accepted: 4056

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)


递归算法在许多搜索最优解的问题当中经常出现,因为一开始问题的规模总是很大用一般的枚举法,模拟法都不能很好的解决。而这时候我们通常会采用分治+递归的方法去求解。先把问题的规模一步步减小,找到最小规模的解后最逐步回朔还原总的解。但是有一点我们要注意的,递归的效率很低,如果不做优化相当于暴力求解。优化的方法就是仔细剖析问题在分解过程中一些重复的或者无用的过程,并且把他们排除在外以达到节省时间的目的。

例如上面这个走迷宫的问题,我们先把问题分解。每次我们做选择会碰到四种情况,即向右,向左,向下,向上。如果下一个位置可以走,那么把原来的位置标记为已经走过,并走到下一个位置。这时候问题有变成从4个方向里选一个,这时候我们可以得出问题的递归部分。问题出口在哪里,很明显当我们走到(4,4)位置的时候我们就认为求解完成。

接下来就是优化的问题,一方面是缩短时间,一方面是保证这条路是最短的。因为入口和出口是固定的所以我们优先走右下两个方向,最优解一定在这两个方向里面。

下面是代码:

// 迷宫问题.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;
stack<int> s1,s2;
int a[5][5]={0};

bool dfs(int i,int j)
{
if(i==4&&j==4)
{
s1.push(i);
s2.push(j);
return true;
}

if(i>=0&&i<=4&&j>=0&&j<=4)
{
if(a[i][j]==0)
{
a[i][j]=1;
if(dfs(i,j+1)||dfs(i+1,j)||dfs(i,j-1)||dfs(i-1,j))//有顺序的 先右下 再左上
{
//printf("%d  %d\n",i,j);
s1.push(i);
s2.push(j);
return true;
}
else
{
a[i][j]=0;
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}

void print()
{
while(!s1.empty())
{
printf("(%d, %d)\n",s1.top(),s2.top());
s1.pop();
s2.pop();
}

}

int main()
{
int temp=0;
while(scanf("%d",&temp)!=EOF)
{
a[0][0]=temp;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
if(i==0&&j==0) continue;
scanf("%d",&a[i][j]);
}
dfs(0,0);
print();

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: