参考:http://caterpillar.onlyfun.net/Gossip/AlgorithmGossip/MouseGoMaze.htm
问题:有一个迷宫,在迷宫的某个出口放着一块奶酪。将一只老鼠由某个入口处放进去,它必须穿过迷宫,找到奶酪。请找出它的行走路径。
解法:这个问题可以用递归的方法去求解。
先来看下面这幅图:
绿色箭头指向的是迷宫的入口,将小老鼠由此放入,红色箭头的位置就是奶酪的所在地,小老鼠必须穿过迷宫从红色箭头标示的地方走出去。
我们用一个二维数组来表示迷宫,用2表示迷宫的墙壁,即上图中的黑色部分,用0表示通路,即上图中老鼠可以行走空白的格子。老鼠每走到一个格子的时候就将该位置的值置为1,表示老鼠的行走路径包括这个格子。
接下来说一下老鼠的行走策略:老鼠每走一步(格子)的时候,将该格子的值置为1,然后会依次考察该格子的右、下、左、上位置的格子是否可走(可走的标志是该格子的值为0)。这样老鼠从入口的格子出发,就会派生出很多可能的行走路径,如果某一条路不能走到终点的话,那么就要将相应的格子的值重新置为0了,表示正确的路径不包括这个格子。
好了,终于到具体的实现代码了:
public class Mouse {
public static void main(String[] args) {
int[][] maze={{2,2,2,0,2,2,2,0,0},
{2,0,0,0,0,0,2,0,0},
{2,0,2,2,2,2,2,2,2},
{0,0,0,0,0,0,0,0,2},
{2,0,2,2,2,2,0,2,2},
{2,0,2,2,0,0,0,2,2},
{2,0,2,2,0,2,2,0,2},
{2,0,2,0,0,0,0,0,0},
{2,0,2,2,2,2,2,2,2}
};
Map map=new Map(maze, new Point(7, 8));
Mouse.go(map, new Point(0,3));
map.print();
}
public static void go(Map map,Point p){
map.step(p);
if(p.y=1)
{
test(map,new Point(p.x, p.y-1));
}
if(p.x>=1)
{
test(map,new Point(p.x-1, p.y));
}
if(!map.isArrived())
map.empty(p);
}
public static void test(Map map,Point p){
if(!map.isArrived() && map.isEmpty(p)){
go(map,p);
}
}
}
class Point{
int x;
int y;
public Point(int x1,int y1){
x=x1;
y=y1;
}
}
class Map{
int[][] maze;
Point end; //终点
public Map(int[][] maze,Point end){
this.maze=maze;
this.end=end;
}
//是否到达终点
public boolean isArrived(){
return maze[end.x][end.y]==1;
}
//当前这一格是否可行
public boolean isEmpty(Point p){
return maze[p.x][p.y]==0;
}
//可以理解为当经过Point p 无法走到终点时,把老鼠走过的痕迹抹去,表示最终的走法不含p
public void empty(Point p){
maze[p.x][p.y]=0;
}
//走到Point p
public void step(Point p){
maze[p.x][p.y]=1;
}
//打印地图,含老鼠走过的路径
public void print(){
for(int i=0;i
运行结果如下:
可见,小老鼠成功地走到了终点。
如果迷宫的设计使得走法不止一种,则只要在老鼠走至出口时显示出所有的路径,然后退回上一格重新选择下一个位置继续递归就可以了。如下图有两种走法。
代码作了一点点儿修改:
public class Mouse {
public static void main(String[] args) {
int[][] maze={{2,2,2,0,2,2,2,0,0},
{2,0,0,0,0,0,2,0,0},
{2,0,2,2,2,0,2,2,2},
{0,0,0,0,0,0,0,0,2},
{2,0,2,2,2,2,0,2,2},
{2,0,2,2,0,0,0,2,2},
{2,0,2,2,0,2,2,0,2},
{2,0,2,0,0,0,0,0,0},
{2,0,2,2,2,2,2,2,2}
};
Map map=new Map(maze, new Point(7, 8));
Mouse.go(map, new Point(0,3));
//map.print();
}
public static void go(Map map,Point p){
map.step(p);
if(map.isArrived())
{
map.print();
map.maze[map.end.x][map.end.y]=0;
}
if(p.y=1)
{
test(map,new Point(p.x, p.y-1));
}
if(p.x>=1)
{
test(map,new Point(p.x-1, p.y));
}
map.empty(p);
}
public static void test(Map map,Point p){
if(!map.isArrived() && map.isEmpty(p)){
go(map,p);
}
}
}
class Point{
int x;
int y;
public Point(int x1,int y1){
x=x1;
y=y1;
}
}
class Map{
int[][] maze;
Point end; //终点
public Map(int[][] maze,Point end){
this.maze=maze;
this.end=end;
}
//是否到达终点
public boolean isArrived(){
return maze[end.x][end.y]==1;
}
//当前这一格是否可行
public boolean isEmpty(Point p){
return maze[p.x][p.y]==0;
}
//可以理解为当经过Point p 无法走到终点时,把老鼠走过的痕迹抹去,表示最终的走法不含p
public void empty(Point p){
maze[p.x][p.y]=0;
}
//走到Point p
public void step(Point p){
maze[p.x][p.y]=1;
}
//打印地图,含老鼠走过的路径
public void print(){
for(int i=0;i
运行结果:
~完~