【手把手带你学JavaSE】(项目展示)老鼠走迷宫和八皇后问题

前言

大家还记得当初C语言我们一起学习的递归吗?说好的要实现老鼠走迷宫和八皇后问题!他来了!!!

老鼠走迷宫

MiGong.java

public class MiGong {

    // 编写一个main方法
    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("===========找路的情况如下===========");

        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 表示走过,但是走不通是死路
    //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
                return false;
            }
        }
    }
}

在这里插入图片描述

八皇后问题

1.问题分析
八皇后问题是一个古老而著名的问题,是回溯算法和递归调用的典型案例。八皇后难题是要将八个皇后(Queen)放在棋盘上,任何两个皇后都不能互相攻击(即没有任意两个皇后是在同一行、同一列或者同一条对角线上),问一共有多少种摆法?
2.步骤分析

  1. 第一个皇后先放在第一行第一列
  2. 第二个皇后放在第二行第一列,然后判断能否在该位置放皇后,如果不可以,则继续放下一列,直至找到一个合适的位置
  3. 继续放置第三个皇后,还是第一列、第二列…直到第8个皇后也能放在一个不能相互攻击的位置,就找到了一个正确解。
  4. 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯。即将第一个皇后放在第一列的所有解逐个得到。
  5. 完成以上步骤之后,将第一个皇后放在第二列,后面循环执行1, 2, 3, 4 步骤。

在这里插入图片描述

Queen.java

class B {
    //定义横竖斜方向上是否有棋子
    public static boolean flag = true;
    //检查棋盘
    public int checBoard(int MAXQUEEN, int row, int col, int[][] Board){
        //行方向上
        for (int i = 0; i < MAXQUEEN; i++) {
            if (Board[row][i] == 1) {
                return 0;
            }
        }
        //列方向上
        for (int i = 0; i < MAXQUEEN; i++) {
            if (Board[i][col] == 1) {
                return 0;
            }
        }
        //右下方向上
        for (int i = row, j = col; i < MAXQUEEN && j < MAXQUEEN; i++, j++) {
            if (Board[i][j] == 1) {
                return 0;
            }
        }
        //左上方向上
        for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
            if (Board[i][j] == 1) {
                return 0;
            }
        }
        //右上方向上
        for (int i = row, j = col; i >= 0 && j < MAXQUEEN ; i--, j++) {
            if (Board[i][j] == 1) {
                return 0;
            }
        }
        //左下方向上
        for (int i = row, j = col; i < MAXQUEEN && j >= 0 ; i++, j--) {
            if (Board[i][j] == 1) {
                return 0;
            }
        }
        if (flag) {
            //此点符合要求,可以下
            Board[row][col] = 1;
            //如果已经到最后一行,则打印棋盘
            if (row == MAXQUEEN - 1) {
                printBoard(MAXQUEEN, Board);
            }
            return 1;
        }
        return 0;
    }
    //打印棋盘
    public static void printBoard(int MAXQUEEN, int[][] Board) {
        for (int i = 0; i < MAXQUEEN; i++) {
            for (int j = 0; j < MAXQUEEN; j++) {
                System.out.print(Board[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("===================");
    }
}
public class Queen {
    public static int MAXQUEEN = 8; //皇后个数,也是棋盘行列数
    public static int[][] Board = new int[MAXQUEEN][MAXQUEEN];  //初始化棋盘
    private static int count;

    //测试方法
    public static void startTest(B b, int row) {
        //第0列开始
        for (int col = 0; col < MAXQUEEN; col++) {
            //检查位置是否可以放棋子
            if (b.checBoard(MAXQUEEN, row, col, Board) == 1) {
                if (row == MAXQUEEN - 1) {
                    count++;
                }
                //递归,向下一行前进
                if (row < MAXQUEEN - 1) {
                    startTest(b,++row);
                    //回退上一个栈
                    --row;
                }
            }
            //重新赋值为0,进行下一次判断
            Board[row][col] = 0;
        }
    }

    //编写一个main方法
    public static void main(String[] args) {
        int row = 0;
        B b1 = new B();
        startTest(b1,row);

        System.out.println("摆放一共有" + count + "种");
    }
}

在这里插入图片描述
在这里插入图片描述

评论 72
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摸鱼王胖嘟嘟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值