zoukankan      html  css  js  c++  java
  • Java实现八皇后

    实验题目   回溯法实现8皇后问题

    实验要求   a.掌握递归回溯算法的基本思想。  

                 b.学习掌握应用面向对象通用回溯程序框架解决实际问题。  提高面向对象编程的技能。

    作业描述:在8*8格的棋盘上放置彼此不受攻击的8个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。8后问题等价于在n*n格的棋盘上放置8个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

     

    package pku.java;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
        private static int SIZE = 8;
        private static int TotalNumber = 0;
        private static List<boolean[][]> ChessBoards = new ArrayList<boolean[][]>();
    
        public static void main(String[] args) {
            boolean[][] chessboard = new boolean[SIZE][SIZE];
            for (int i = 0; i < SIZE; ++i) {
                for (int j = 0; j < SIZE; ++j) {
                    chessboard[i][j] = false;
                }
            }
            Main Test = new Main();
            Test.put(chessboard, 0);
            Test.print(ChessBoards.get((int) (Math.random() * 1000)
                    % ChessBoards.size()));
            System.out.println(TotalNumber);
        }
    
        public void print(boolean[][] chessboard) {
            for (int i = 0; i < SIZE; i++) {
                for (int k = 0; k < SIZE; k++) {
                    if (chessboard[i][k] == true)
                        System.out.print("# ");
                    if (chessboard[i][k] == false)
                        System.out.print(". ");
                }
                System.out.println();
            }
        }
    
        public void put(boolean[][] chessboard, int level) {
            // 放皇后
            if (level == SIZE - 1) {
                for (int j = 0; j < SIZE; j++) {
                    chessboard[level][j] = true;
                    if (safeJudge(chessboard, level, j)) {
                        // 放最后一个皇后
                        boolean[][] temp = new boolean[SIZE][SIZE];
                        for (int i = 0; i < SIZE; i++) {
                            for (int k = 0; k < SIZE; k++) {
                                temp[i][k] = chessboard[i][k];
                            }
                        }
                        ChessBoards.add(temp);
                        TotalNumber++;
                    }
                    chessboard[level][j] = false;
                }
            } else {
                for (int j = 0; j < SIZE; j++) {
                    chessboard[level][j] = true;
                    if (safeJudge(chessboard, level, j)) {
                        put(chessboard, level + 1);
                    }
                    chessboard[level][j] = false;
                }
            }
        }
    
        public boolean safeJudge(boolean[][] chessboard, int x, int y) {
            // 放皇后时,判断放下是否安全,因为是逐行放,水平方向不会冲突
            // int x_count = 0;
            int y_count = 0;
            // x-direction
            // for (int j = 0; j < SIZE; j++) {
            // if (chessboard[x][j] == true) {
            // ++x_count;
            // }
            // if (x_count > 1)
            // return false;
            // }
            // y-direction
            for (int i = 0; i < SIZE; i++) {
                if (chessboard[i][y] == true) {
                    ++y_count;
                }
                if (y_count > 1)
                    return false;
            }
            // oblique-direction
            // 主对角线
            int z_count = 0;
            for (int i = x, j = y; i >= 0 && j >= 0; --i, --j) {
                if (chessboard[i][j] == true)
                    ++z_count;
                if (z_count > 1)
                    return false;
            }
            z_count = 0;
            for (int i = x, j = y; i < SIZE && j < SIZE; ++i, ++j) {
                if (chessboard[i][j] == true)
                    ++z_count;
                if (z_count > 1)
                    return false;
            }
            // 副对角线
            int w_count = 0;
            for (int i = x, j = y; i >= 0 && j < SIZE; --i, ++j) {
                if (chessboard[i][j] == true)
                    ++w_count;
                if (w_count > 1)
                    return false;
            }
            w_count = 0;
            for (int i = x, j = y; i < SIZE && j >= 0; ++i, --j) {
                if (chessboard[i][j] == true)
                    ++w_count;
                if (w_count > 1)
                    return false;
            }
            return true;
        }
    }
  • 相关阅读:
    Asymptote 学习记录(1):基本的安装以及用批处理模式和交互模式绘图
    导函数的介质定理
    在新浪云上建立了一个wordpress独立博客
    数学分析原理 定理 6.10
    数学分析原理 定理 6.12
    opencvSparseMat稀疏矩阵
    基于MRSHudi构建数据湖的典型应用场景介绍
    解析云原生2.0架构设计的8大关键趋势
    全链路数据血缘在满帮的实践
    10年经验总结,华为fellow教你如何成为一名优秀的架构师?
  • 原文地址:https://www.cnblogs.com/aboutblank/p/3330900.html
Copyright © 2011-2022 走看看