• 105-算法应用【N皇后问题】代码实现


    问题应用:N皇后问题

    算法主要思想:动态规划(构建树解)、BFS

    算法核心代码实现:

      1 //https://www.cnblogs.com/cheng2839
      2 class QueensContainer {
      3     int n = -1;//n代表容器大小,及放置n个皇后
      4     int[][] containers; //容器;0:可放置,1:皇后,-1:不可放置
      5     State solvedTree;
      6     List<int[][]> result = new ArrayList<>();
      7 
      8     public QueensContainer(int n) {
      9         this.n = n;
     10         containers = new int[n][n];
     11 
     12         State solvedTreeRoot = new State();
     13         solvedTreeRoot.cs = this.containers;
     14         for (int i = 0; i < containers.length; i++) {
     15             State s = new State();
     16             s.h++;
     17             int[][] cs = clone(containers);
     18             cs[0][i] = 1;
     19             update(0, i, cs);
     20             s.cs = cs;
     21             solvedTreeRoot.children.add(s);
     22         }
     23         this.buildSolvedTree(solvedTreeRoot.children);
     24 
     25         this.solvedTree = solvedTreeRoot;
     26     }
     27 
     28     class State {
     29         int h = 0;
     30         int[][] cs;
     31         List<State> children = new ArrayList<>();
     32     }
     33 
     34     //原文:https://www.cnblogs.com/cheng2839
     35     void buildSolvedTree(List<State> root) {
     36         if (null == root || root.size() == 0)
     37             return;
     38         for (State state : root) {
     39             int h = state.h;
     40             if (h == state.cs.length)
     41                 continue;
     42 
     43             int[] is = state.cs[h];
     44             for (int i = 0; i < is.length; i++) {
     45                 if (is[i] == 0) {
     46                     State s = new State();
     47                     s.h = h + 1;
     48                     int[][] cs = clone(state.cs);
     49                     cs[h][i] = 1;
     50                     update(h, i, cs);
     51                     s.cs = cs;
     52                     state.children.add(s);
     53                 }
     54             }
     55             buildSolvedTree(state.children);
     56         }
     57     }
     58 
     59     //原文:https://www.cnblogs.com/cheng2839
     60     void bfs(List<State> root) {
     61         if (null == root || root.size() == 0)
     62             return;
     63         for (State s : root) {
     64             if (null == s.children || s.children.size() == 0) {
     65                 int n = 0;
     66                 for (int i = 0; i < s.cs.length; i++) {
     67                     for (int j = 0; j < s.cs[i].length; j++) {
     68                         n += s.cs[i][j]==1 ? 1 : 0;
     69                     }
     70                 }
     71                 if (n == s.cs.length)
     72                     result.add(s.cs);
     73                 continue;
     74             }
     75             bfs(s.children);
     76         }
     77     }
     78 
     79     //第i,j位置放置皇后,更新容器
     80     //原文:https://www.cnblogs.com/cheng2839
     81     boolean update(int i, int j, int[][] con) {
     82         for (int k = 0; k < con.length; k++) {
     83             for (int l = 0; l < con[k].length; l++) {
     84                 int d = con[k][l];
     85                 if (k == i && l == j) {
     86                     continue;
     87                 }
     88 
     89                 boolean dead = false;
     90                 if (k == i) {
     91                     dead = true;
     92                 }
     93                 if (l == j) {
     94                     dead = true;
     95                 }
     96                 if (k-i == l-j) {
     97                     dead = true;
     98                 }
     99                 if (k-i == j-l) {
    100                     dead = true;
    101                 }
    102                 if (dead && d == 0) {
    103                     con[k][l] = -1;
    104                     continue;
    105                 }
    106                 if (dead && d == -1) {
    107                     continue;
    108                 }
    109                 if (dead && d == 1) {
    110                     return false;
    111                 }
    112             }
    113         }
    114         return true;
    115     }
    116 
    117     public void print(int[][] con) {
    118         StringBuilder stringBuilder = new StringBuilder();
    119         for (int i = 0; i < con.length; i++) {
    120             for (int j = 0; j < con[i].length; j++) {
    121                 stringBuilder.append(con[i][j]==-1?0:con[i][j]);
    122                 if (j < con[i].length-1) {
    123                     stringBuilder.append(", ");
    124                 }
    125             }
    126             if (i < con.length-1) {
    127                 stringBuilder.append("
    ");
    128             }
    129         }
    130         System.out.println(stringBuilder.toString());
    131     }
    132 
    133     int[][] clone(int[][] con) {
    134         int[][] newCon = new int[con.length][con[0].length];
    135         for (int i = 0; i < con.length; i++) {
    136             for (int j = 0; j < con[i].length; j++) {
    137                 newCon[i][j] = con[i][j];
    138             }
    139         }
    140         return newCon;
    141     }
    142 }

    结果展示:

    (输出分控制台打印可视图形化)可视化图形可通过按键(上下/左右)查看结果

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Description N皇后问题
     * @Author https://www.cnblogs.com/cheng2839
     * @Date 2021年3月22日
     * @Version v1.0
     */
    public class NQueens {
    
        static class MyFrame extends JPanel {
            JFrame jFrame = new JFrame();
            static final int SIZE = 50;
            static final int L = 3;
            int[][] data = null; //一个解
            static int DATA_INDEX = 0;
            static List<int[][]> result; //全部解
            public MyFrame(int n, List<int[][]> result) {
                MyFrame.result = result;
                jFrame.setTitle(n+"皇后问题—第"+(DATA_INDEX+1)+"/"+result.size()+"个解");
                data = result.get(DATA_INDEX);
                jFrame.setLayout(new CardLayout());
                jFrame.setBounds(0, 0, 500, 500);
                this.setBackground(Color.WHITE);
                jFrame.addKeyListener(new KeyAdapter() {
                    public void keyReleased(KeyEvent e) {
                        if (e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_UP) {
                            DATA_INDEX = Math.min(DATA_INDEX+1, result.size()-1);
                        } else if (e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_DOWN) {
                            DATA_INDEX = Math.max(DATA_INDEX-1, 0);
                        }
                        data = result.get(DATA_INDEX);
                        jFrame.setTitle(n+"皇后问题—第"+(DATA_INDEX+1)+"/"+result.size()+"个解");
                        MyFrame.this.repaint();
                    }
                });
                /*new Thread(()->{
                    while (true)
                        this.repaint(50);
                }).start();*/
                jFrame.add(this);
                jFrame.setVisible(true);
                jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
    
            @Override
            public void paintComponent(Graphics g0) {
                if (null == data)return;
                Graphics2D g = (Graphics2D) g0;
                int w, h = -L;
                for (int i = 0; i < data.length; i++) {
                    w = 0; h += L;
                    for (int j = 0; j < data[i].length; j++) {
                        g.setColor(data[i][j] == 1 ? Color.RED : Color.LIGHT_GRAY);
                        g.fillRect(i * SIZE + h, j * SIZE + w, SIZE, SIZE);
                        w += L;
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            int n = 8;
            QueensContainer qc = new QueensContainer(n);
            QueensContainer.State root = qc.solvedTree;
            qc.bfs(root.children);
            List<int[][]> result = qc.result;
    
            //可视化图形界面
            new MyFrame(n, result);
    
            //控制台打印方式
            /*System.out.println("一共求出"+result.size()+"组解。");
            for (int[][] rs : result) {
                qc.print(rs);
                System.out.print("
    ");
            }*/
        }
    }
    ____________________________特此,勉励____________________________
    本文作者cheng2839
    本文链接https://www.cnblogs.com/cheng2839
    关于博主:评论和私信会在第一时间回复。
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
  • 相关阅读:
    centos7 yum 安装mariadb
    curl 获取外网IP
    ansible之一:安装与配置
    第一步 django的下载安装
    命名空间的三种引用方式:非限定名称、限定名称、完全限定名称
    重温PHP之快速排序
    PHP实现文件下载的核心代码
    PHP常量定义之define与const对比
    ThinkPHP中I('post.')与create()方法的对比
    重温PHP之选择排序
  • 原文地址:https://www.cnblogs.com/cheng2839/p/14922935.html
Copyright © 2020-2023  润新知