1. 迷宫问题 221-224

java迷宫问题_i++

//迷宫问题  221
public class Test29
{
public static void main(String[] args)
{
//思路
//1. 先创建迷宫,用二维数组表示 int[][] map = new int[8][7];
//2. 先规定 map 数组的元素值: 0 表示可以走 1 表示障碍物
int map[][] = new int[8][7];
//3. 将最上面的一行和最下面的一行,全部设置为 1
for(int i=0;i<7;i++)
{
map[0][i]=1;//第一行
map[7][i]=1;//最后一行
}
//4.将最右面的一列和最左面的一列,全部设置为 1
for(int i=0;i<8;i++)
{
map[i][0]=1;//最左列
map[i][6]=1;//最右列
}
//单独设置障碍物
map[3][1]=1;
map[3][2]=1;

//输出当前的地图
System.out.println("====找路的情况====");
for(int i=0;i<map.length;i++)
{
for(int j=0;j<map[i].length;j++)
{
System.out.print(map[i][j]+" ");
}
System.out.println();
}

//使用findWay给老鼠找路
T t1 = new T();
t1.findWay(map,1,1);

System.out.println("\n====找路的情况====");
for(int i=0;i<map.length;i++)
{
for(int j=0;j<map[i].length;j++)
{
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
}

class T
{
//使用递归回溯的思想解决老鼠出迷宫问题
//解读
//1. findWay 方法就是专门来找出迷宫的路径
//2. 如果找到,就返回 true ,否则返回 false
//3. map 就是二维数组,即表示迷宫
//4. i,j 就是老鼠的位置,初始化的位置为(1,1)
//5. 因为我们是递归的找路,所以我先规定 map 数组的各个值的含义
// 0表示可以走 1 表示障碍物 2 表示可以走通 3 表示走过,但是走不通是死路(说明2 3就相当于做记号,能走通标2,不能标3)
//6. 当 map[6][5] =2 就说明找到通路,就可以结束,否则就继续找.
//7. 先确定老鼠找路策略 下->右->上->左
public boolean findWay(int map[][],int i,int j)
{
if(map[6][5]==2)//说明已经找到路线
{
return true;
}
else//说明还没找到路线
{
if(map[i][j]==0)//为0,表示可以走
{
//我们假定可以走通
map[i][j]=2;
//使用策略,来确定该位置是否可以走通
//找路策略 下->右->上->左
if(findWay(map,i+1,j))//向下
{
return true;
}
else if(findWay(map,i,j+1))//向右
{
return true;
}
else if(findWay(map,i-1,j))//向上
{
return true;
}
else if(findWay(map,i,j-1))//向左
{
return true;
}
else
{
map[i][j]=3;//如果上下左右都走不通,表示我们的假定是错误的
return false;
}
}
else//map[i][j]=1,2,3,这三种情况都不需要再走了(说一下2,因为2表示已经走通即走过当然不用走啦)
{
return false;
}
}
}
}

1.1 分析

如果我将起始位置(1,1)周围都设成墙,系统会将(1,1)赋值成3,然后直接退出程序

java迷宫问题_迷宫问题_02

1.2 回溯现象

但如果我只将(2,2)位置变成墙,系统会产生回溯现象,回溯是当小球向下走到(2,1)时,继续遵循下右上左的策略,发现此时都走不通,于是将(2,1)位置赋值成3,返回(1,1)位置,接着向右走去

java迷宫问题_System_03

2. 汉诺塔

//汉诺塔  225
public class Test29
{
public static void main(String[] args)
{
Tower t1 = new Tower();
t1.move(3,'A','B','C');
}
}
class Tower
{
public void move(int num,char a,char b,char c)
{
//num 表示要移动的个数, a, b, c 分别表示 A 塔,B 塔, C 塔
if(num==1)//假如只有一个盘
{
System.out.println(a+"->"+c);
}
else//如果有多个盘,可以看成两个 , 最下面的和上面的所有盘(num-1)
{
//(1)先移动a上面所有的盘到 b, 借助 c
move(num-1,a,c,b);
//(2)把最下面的这个盘,移动到 c
System.out.println(a+"->"+c);
//(3)再把 b 塔的所有盘,移动到 c ,借助 a
move(num-1,b,a,c);
}
}
}