zoukankan      html  css  js  c++  java
  • 易理解java代码8皇后问题

    马上就要蓝桥杯比赛了,我这些算法还是不会,确实有点慌,今天一天早上睡到很晚不愿起床,然后才开始研究8皇后问题。这也是典型的回溯与递归问题。其实本质上和马踏棋盘问题非常类似,八皇后问题呢,就是要判断主对角线,副对角线,横排和竖排不能有皇后。这个是这个问题的着重点。先来看下八皇后问题吧。

    1.问题描述:

        在8*8的棋盘中放8个皇后,使得每个皇后不能放在同一行,同一列,同一主对角线上(左下斜),同一副对角线上(右上斜)。

    2.输入: 无(当然也可以优化求任意皇后,这个就不是重点了)

    3.输出示例:

          1  *  *  *  *  *  *  *
          *  *  *  *  2  *  *  *
          *  *  *  *  *  *  *  3
          *  *  *  *  *  4  *  *
          *  *  5  *  *  *  *  *
          *  *  *  *  *  *  6  *
          *  7  *  *  *  *  *  *
          *  *  *  8  *  *  *  *

        ===============

          1  *  *  *  *  *  *  *
          *  *  *  *  *  2  *  *
          *  *  *  *  *  *  *  3
          *  *  4  *  *  *  *  *
          *  *  *  *  *  *  5  *
          *  *  *  6  *  *  *  *
          *  7  *  *  *  *  *  *
          *  *  *  *  8  *  *  *

        ===============

        ...........

        共有92种方法

    4.算法思路:

        这题整体思想是用到递归与回溯,与马踏棋盘非常类似,但是比马踏棋盘问题要难,因为得判断对角线是否冲突,我这里判断是用一个vis[3][20]数组,为什么开始是3呢,因为本身是要判断4个方向不能有皇后的,但是递归是每一列,每一列的递归x,x+1.....这样必然不会在同一列上造成有皇后,则只需要另外3个方向,0表示同一行有皇后,1表示主对角线有皇后,2表示副对角线上有皇后。另外呢,怎么判断这些对角线上是否有皇后 呢?  如果我在第x列,第i行放了元素,那么vis[0][i] = 1表示我在第i行放了元素了。vis[1][x+i] = 1,表示如果我在第x列,第i行放了皇后,那么副对角线上,第x+1列,i-1行数就不能放皇后,第x-1列,第i+1行就不能放皇后,正好都是在副对角线上。vis[2][x-i+8] = 1,表示如果x==i了,那么恒等于vis[2][8] = 1就不能放了,即是主对角线。有了这三个条件既可以了。

    5.代码如下:

    import java.util.Scanner;
    
    public class EightQueen {
        static int qipan[][] = new int[8][8];
        static int count = 0;
        static int step = 1;
        static int vis[][] = new int[3][20]; //三种情况主对角线,副对角线,行有没有被占用。
        public static void main(String[] args) {
            //初始化棋盘
            for(int i=0;i<8;i++){
                for(int j=0;j<8;j++){
                    qipan[i][j] = 0;
                }
            }
            for(int i=0;i<vis.length;i++){
                for(int j=0;j<vis[i].length;j++){
                    vis[i][j] = 0;
                }
            }
            
            move(0);
            //从第0个位置开始放第一个皇后,没得说,只要求出皇后的位置,和摆放的数量即可。
            System.out.println("count = " + count);
        }
        public static void move(int x) {
            int next_x = x+1;
            if(step>8){
                for(int i=0;i<8;i++){
                    for(int j=0;j<8;j++){
                        if(qipan[i][j] == 0){
                            System.out.printf("%3c",'*'); //把没有皇后,棋盘是0的位置用*输出,显得好看一点
                        }else{
                            System.out.printf("%3d",qipan[i][j]);
                        }
                        
                    }
                    System.out.println();
                }
                System.out.println("========================");
                count++;
            }else{
                for(int i=0;i<8;i++){
                    if(vis[0][i]==0 && vis[1][x+i]==0 && vis[2][x-i+8]==0){//满足摆放条件
                        qipan[x][i] = step;
                        step++;
                        vis[0][i]=1; vis[1][x+i]=1; vis[2][x-i+8]=1;
                        move(next_x);
                        qipan[x][i] = 0;
                        vis[0][i]=0; vis[1][x+i]=0; vis[2][x-i+8]=0;
                        step--;
                        
                    }
                }
            }
        }
    }
    

      

  • 相关阅读:
    Insus Meta Utility
    The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
    Insus Binary Utility
    asp.net实现文件下载功能
    Column 'Column Name' does not belong to table Table
    程序已被编译为DLL,怎样去修改程序功能
    如何在Web网站实现搜索功能
    如何把数据流转换为二进制字符串
    Asp.net更新文件夹的文件
    如何显示中文月份
  • 原文地址:https://www.cnblogs.com/zzlback/p/8467877.html
Copyright © 2011-2022 走看看