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 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
原文地址:https://www.cnblogs.com/cheng2839/p/14922935.html