`
qingwei201314
  • 浏览: 167977 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

八皇后问题

 
阅读更多

大学没用心读书,八皇后问题令我望而生畏,这几天零零散散将其写完,并调试完成,感觉不难。当补交大学时的作业。总共92个解,12个解是独立的。

package com.kevin.queen;

public class EightQueen {
    static int[][] queens = new int[8][8];
    // 最近一子位置
    static int curI = -1;
    static int curJ = -1;
    // 第1子位置
    static int oneI = -1;
    static int oneJ = -1;

    static int times = 0;

    // 总答案集合
    static int[][][] total = new int[92][8][8];
    static int[][] flag = new int[92][1];

    public static void main(String[] args) {
        for (int i = 0; i < 8; i++) {
            reset();
            setQueen(1, 0, i);
        }
        // 求出独立解
        // 初始化标识位
        for (int i = 0; i < 92; i++) {
            flag[i][0] = 1;
        }
        // 去重
        int resultOne = 0;
        int[][] temp = new int[8][8];
        for (int time = 0; time < 92; time++) {
            if (flag[time][0] == 1) {
                // 拿出结果
                for (int i = 0; i < 8; i++) {
                    for (int j = 0; j < 8; j++) {
                        temp[i][j] = total[time][i][j];
                    }
                }
                // 打印结果
                resultOne++;
                System.out.println("独立:" + resultOne);
                printResultOnly(temp);

                // 转换
                int[][] tsfResultEast = transferEast(temp);
                int[][] tsfResultSouth = transferSouth(temp);
                int[][] tsfResultWest = transferWest(temp);
                //翻过来
                int[][] contrast = contrast(temp);
                int[][] contrastEast = transferEast(contrast);
                int[][] contrastSouth = transferSouth(contrast);
                int[][] contrastWest = transferWest(contrast);
               
                //对比
                for(int timeTemp = time + 1; timeTemp < 92; timeTemp++){
                    boolean same = true;
                    isSame: for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            if(total[timeTemp][i][j] != tsfResultEast[i][j]){
                                same = false;
                                break isSame;
                            }
                        }
                    }
                    if(same){
                        flag[timeTemp][0] = 0;
                    }
                   
                    same = true;
                    isSame: for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            if(total[timeTemp][i][j] != tsfResultSouth[i][j]){
                                same = false;
                                break isSame;
                            }
                        }
                    }
                    if(same){
                        flag[timeTemp][0] = 0;
                    }
                   
                    same = true;
                    isSame: for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            if(total[timeTemp][i][j] != tsfResultWest[i][j]){
                                same = false;
                                break isSame;
                            }
                        }
                    }
                    if(same){
                        flag[timeTemp][0] = 0;
                    }
                   
                    same = true;
                    isSame: for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            if(total[timeTemp][i][j] != contrast[i][j]){
                                same = false;
                                break isSame;
                            }
                        }
                    }
                    if(same){
                        flag[timeTemp][0] = 0;
                    }
                   
                    same = true;
                    isSame: for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            if(total[timeTemp][i][j] != contrastEast[i][j]){
                                same = false;
                                break isSame;
                            }
                        }
                    }
                    if(same){
                        flag[timeTemp][0] = 0;
                    }
                   
                    same = true;
                    isSame: for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            if(total[timeTemp][i][j] != contrastSouth[i][j]){
                                same = false;
                                break isSame;
                            }
                        }
                    }
                    if(same){
                        flag[timeTemp][0] = 0;
                    }
                   
                    same = true;
                    isSame: for (int i = 0; i < 8; i++) {
                        for (int j = 0; j < 8; j++) {
                            if(total[timeTemp][i][j] != contrastWest[i][j]){
                                same = false;
                                break isSame;
                            }
                        }
                    }
                    if(same){
                        flag[timeTemp][0] = 0;
                    }
                }
            }
        }
    }

    /**
     * 放子
     *
     * @param queen
     *            当前在放的子
     * @param pI
     *            开始放的横坐标
     * @param pJ
     *            开始放的纵坐标
     */
    private static void setQueen(int queen, int pI, int pJ) {
        // printTest();

        // 放子是否成功
        boolean success = false;
        int i = pI >= 0 ? pI : 0;
        int j = pJ >= 0 ? pJ : 0;

        line: for (; i < 8; i++) {
            for (; j < 8; j++) {
                if (queens[i][j] == 0 && i == queen - 1) {
                    success = true;
                    queens[i][j] = 100 + queen;
                    curI = i;
                    curJ = j;

                    // 设置第1子位置
                    if (queen == 1) {
                        oneI = i;
                        oneJ = j;
                    }

                    // 将影响的格增加1
                    setOne(true, curI, curJ);

                    // 放完后,要退出
                    break line;
                }
            }
            j = 0;
        }

        // 下一子开始放的坐标
        int nextI = curI;
        int nextJ = curJ;
        if (success) { // 如果放子成功
            if (queen >= 8) {
                times++;
                printResult(queens);
                // 将最后一子拿掉, 将影响的格减少1
                queens[curI][curJ] = 0;
                setOne(false, curI, curJ);
                // 如果最后一子,刚好放在最后一格
                if (curI == 7 && curJ == 7) {
                    queen = queen - 1;
                    int[] result = previous(queen);
                    nextI = result[1];
                    nextJ = result[2];
                }
            } else {
                queen = queen + 1;
            }
            // 将位置向前移动一格
            if (nextJ < 7) {
                nextJ += 1;
            } else if (nextI < 7) {
                nextI += 1;
                nextJ = 0;
            } else {
                // 如果向前移动已到最后
                return;
            }
        } else { // 如果放子失败,说明方案错误 ,重置
            queen = queen - 1;
            if (queen <= 1) {
                return;
            }

            // 将要放的子拿掉
            int[] results = previous(queen);
            // 如果向前移动已到最后
            if (results[0] == 0) {
                return;
            }

            nextI = results[1];
            nextJ = results[2];
        }
        setQueen(queen, nextI, nextJ);
    }

    /**
     * 重置
     */
    private static void reset() {
        // 最近一子位置
        curI = -1;
        curJ = -1;

        oneI = -1;
        oneJ = -1;

        // 初始化
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                queens[i][j] = 0;
            }
        }
    }

    /**
     * 打印结果
     */
    private static void printResult(int[][] result) {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (result[i][j] > 100) {
                    total[times - 1][i][j] = 1;
                    System.out.print(result[i][j] + "      ");
                } else {
                    total[times - 1][i][j] = 0;
                    System.out.print(result[i][j] + "        ");
                }
            }
            System.out.println("");
        }
        System.out.println("==============================================  " + times);
    }
   
    /**
     * 打印独立解
     * @param result
     */
    private static void printResultOnly(int[][] result) {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(result[i][j] + "        ");
            }
            System.out.println("");
        }
    }
   
   

    /**
     * 将影响的格设置为1 isSet: 是否放子。 true: 放子; false: 拿子
     */
    private static void setOne(boolean isSet, int x, int y) {
        // 将当前子所影响的格置为1
        // 处理当前行
        for (int k = 0; k < 8; k++) {
            if (k != y) {
                if (queens[x][k] < 100) {
                    if (isSet) {
                        queens[x][k] += 1;
                    } else {
                        if (queens[x][k] >= 1) {
                            queens[x][k] -= 1;
                        }
                    }
                }
            }
        }
        // 处理当前列
        for (int k = 0; k < 8; k++) {
            if (k != x) {
                if (queens[k][y] < 100) {
                    if (isSet) {
                        queens[k][y] += 1;
                    } else {
                        if (queens[k][y] >= 1) {
                            queens[k][y] -= 1;
                        }
                    }
                }
            }
        }
        // 处理左上角斜线
        int topLeftI = x;
        int topLeftJ = y;
        while (true) {
            topLeftI -= 1;
            topLeftJ -= 1;
            if (topLeftI < 0 || topLeftJ < 0) {
                break;
            }
            if (queens[topLeftI][topLeftJ] < 100) {
                if (isSet) {
                    queens[topLeftI][topLeftJ] += 1;
                } else {
                    if (queens[topLeftI][topLeftJ] >= 1) {
                        queens[topLeftI][topLeftJ] -= 1;
                    }
                }
            }
        }
        // 处理右下角斜线
        topLeftI = x;
        topLeftJ = y;
        while (true) {
            topLeftI += 1;
            topLeftJ += 1;
            if (topLeftI > 7 || topLeftJ > 7) {
                break;
            }
            if (queens[topLeftI][topLeftJ] < 100) {
                if (isSet) {
                    queens[topLeftI][topLeftJ] += 1;
                } else {
                    if (queens[topLeftI][topLeftJ] >= 1) {
                        queens[topLeftI][topLeftJ] -= 1;
                    }
                }
            }
        }
        // 处理右上角斜线
        topLeftI = x;
        topLeftJ = y;
        while (true) {
            topLeftI -= 1;
            topLeftJ += 1;
            if (topLeftI < 0 || topLeftJ > 7) {
                break;
            }
            if (queens[topLeftI][topLeftJ] < 100) {
                if (isSet) {
                    queens[topLeftI][topLeftJ] += 1;
                } else {
                    if (queens[topLeftI][topLeftJ] >= 1) {
                        queens[topLeftI][topLeftJ] -= 1;
                    }
                }
            }
        }
        // 处理左下角斜线
        topLeftI = x;
        topLeftJ = y;
        while (true) {
            topLeftI += 1;
            topLeftJ -= 1;
            if (topLeftI > 7 || topLeftJ < 0) {
                break;
            }
            if (queens[topLeftI][topLeftJ] < 100) {
                if (isSet) {
                    queens[topLeftI][topLeftJ] += 1;
                } else {
                    if (queens[topLeftI][topLeftJ] >= 1) {
                        queens[topLeftI][topLeftJ] -= 1;
                    }
                }
            }
        }
    }

    /**
     * 将上一子拿掉
     */
    public static int[] previous(int queen) {
        int[] result = new int[3];
        result[0] = 1;

        // 将要放的子拿掉
        int tempK = 0;
        int tempL = 0;
        line: for (int k = 0; k < 8; k++) {
            for (int l = 0; l < 8; l++) {
                if (queens[k][l] == 100 + queen) {
                    queens[k][l] = 0;
                    tempK = k;
                    tempL = l;
                    break line;
                }
            }
        }
        // 将影响的格减少1
        setOne(false, tempK, tempL);
        // 将位置向前移动一格
        if (tempL < 7) {
            tempL += 1;
        } else if (tempK < 7) {
            tempK += 1;
            tempL = 0;
        } else {
            // 如果向前移动已到最后
            result[0] = 0;
        }

        result[1] = tempK;
        result[2] = tempL;

        return result;
    }

    /**
     * 将矩阵进行旋转:东
     */
    private static int[][] transferEast(int[][] temp) {
        int[][] result = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                result[j][8 - 1 - i] = temp[i][j];
            }
        }
        return result;
    }
   
    /**
     * 将矩阵进行旋转: 南
     */
    private static int[][] transferSouth(int[][] temp) {
        int[][] result = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                result[8 - 1 - i][8 - 1 - j] = temp[i][j];
            }
        }
        return result;
    }
   
    /**
     * 将矩阵进行旋转: 西
     */
    private static int[][] transferWest(int[][] temp) {
        int[][] result = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                result[8 - 1 - j][i] = temp[i][j];
            }
        }
        return result;
    }
   
    /**
     * 翻过来
     */
    private static int[][] contrast(int[][] temp) {
        int[][] result = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                result[i][8 - 1 - j] = temp[i][j];
            }
        }
        return result;
    }
   
   
    /**
     * 打印中间结果,用于测试
     */
    private static void printTest() {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (queens[i][j] > 100) {
                    System.out.print(queens[i][j] + "      ");
                } else {
                    System.out.print(queens[i][j] + "        ");
                }

            }
            System.out.println("");
        }
        System.out.println("-----------------------------");
    }
}

分享到:
评论

相关推荐

    mfc实现八皇后问题

    八皇后问题是一个经典的计算机编程问题,它涉及到回溯算法、数据结构和图形用户界面的设计。在C++中,特别是结合MFC(Microsoft Foundation Classes)框架,可以创建具有用户友好界面的程序来解决此问题。 首先,...

    八皇后问题详细的解法-23页 PPT PDF版.pdf

    ### 八皇后问题详解 #### 一、八皇后问题背景 八皇后问题是一个经典的计算机科学问题,也是数学领域中一个有趣的挑战。这个问题来源于国际象棋的背景:如何在一个8×8的国际象棋棋盘上放置八个皇后,使得没有任何...

    爬山法、模拟退火法、遗传算法实现八皇后问题

    它们被应用于解决各种复杂问题,包括经典的八皇后问题。八皇后问题是一个著名的棋盘放置问题,要求在8×8的棋盘上摆放8个皇后,使得任意两个皇后都不能在同一行、同一列或同一对角线上。下面将详细解释这些方法以及...

    八皇后问题 c++ 八皇后问题 c++

    八皇后问题 c++ 八皇后问题 c++ 八皇后问题 c++

    八皇后问题回溯求解 matlab

    用回溯求解法求解八皇后问题,经典问题matlab实现,欢迎大家下载

    数据结构八皇后问题实验报告

    数据结构八皇后问题实验报告是一份详尽的项目文档,主要涵盖了八皇后问题的解决方案,该问题是一个经典的计算机科学和算法问题,源自国际象棋。报告的作者花费了两周时间完成,显然投入了大量的精力和思考。 八皇后...

    八皇后问题课程设计论文

    八皇后问题课程设计论文

    八皇后问题源码 python

    解决八皇后问题的源码,带有注释,由于数据结构即算法的学习,如有其他需要,请留言

    汇编解决八皇后问题

    作业代码,汇编写八皇后问题,自己写了一份,在网上找的也在里面

    C++八皇后问题代码,递归实现

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或...

    八皇后问题的c语言实现

    linux c语言实现八皇后问题。希望对你的学习

    八皇后问题 C语言

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一...

    八皇后问题求解 java

    八皇后问题是一个经典的问题,在棋盘上放置八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。这个问题最早由数学家欧拉提出,后来被广泛用来作为回溯法的典型示例。在这个Java程序...

    八皇后问题MFC实现

    八皇后问题是计算机科学中一个经典的回溯算法应用实例,它要求在8×8的棋盘上摆放8个皇后,使得任何两个皇后都无法在同一行、同一列或同一对角线上互相攻击。这个问题最早由数学家路易斯·卡洛在19世纪提出,至今...

    Python实现八皇后问题示例代码

    ### Python 实现八皇后问题详解 #### 一、八皇后问题背景及定义 八皇后问题是一个经典的计算机科学问题,最早由国际象棋爱好者马克斯·贝瑟尔在1848年提出。该问题是在一个8×8的国际象棋棋盘上放置8个皇后,使得...

    八皇后问题C++ 代码

    这个文档关于八皇后问题,一共两种代码,输出分别为0和1的矩阵或者直接输出位置序号两种输出结果。代码是C++语言编写。

    数据结构课程作业八皇后问题源代码

    八皇后问题源代码解析 八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。它的目标是在n×n格的棋盘上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。解决这个问题...

    八皇后问题 递归算法 可以输入皇后的值

    八皇后问题 递归算法 可以输入皇后的值 输出排列的结果

    回溯算法求解 八皇后问题

    八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线...

    八皇后问题c++回溯法

    经典的算法,八皇后问题,c++实现,回溯法

Global site tag (gtag.js) - Google Analytics