Video link: Han Ping's Java data structure and algorithm -- 8 Queen Problem
Eight emperors and empress N
VIII. Introduction to questions:
The eight queens problem is an ancient and famous problem and a typical case of backtracking algorithm. The problem was put forward by international chess player Max Bethel in 1848: in August × Eight queens are placed on the 8-grid chess so that they can't attack each other, that is, any two Queens can't be in the same row, column or slash. Ask how many kinds of pendulum methods there are (92).
Analysis of algorithm ideas:
- The first queen puts the first row and the first column first
- The second queen is placed in the first column of the second row, and then judge whether it is OK. If it is not OK, continue to put it in the second column and the third column, and put all the columns in turn to find a suitable one
- Continue the third queen, or the first and second columns... Until the eighth queen can also be placed in a non conflict position, it can be regarded as finding a correct solution
- When a correct solution is obtained, when the stack returns to the previous stack, it will start backtracking, that is, the first queen will get all the correct solutions put in the first column
- Then go back and continue to put the first queen in the second column, and then continue to cycle through steps 1, 2, 3 and 4
- Sketch Map:
- explain:
Theoretically, we should create a two-dimensional array to represent the chessboard, but in fact, we can solve the problem by using a one-dimensional array through the algorithm. Arr [8] = {0, 4, 7, 5, 2, 6, 1, 3} / / the corresponding arr subscript indicates the row, that is, the queen. arr[i] = val, val indicates the i+1 Queen, which is placed in column val+1 of row i+1.
Teacher Han's code:
public class Queue8 { public static void main(String[] args) { // Test whether the 8 Queen is correct Queue8 queue8 = new Queue8(); queue8.check(0); System.out.printf("Altogether%d solution", count); System.out.println(); System.out.printf("Total number of conflicts judged%d second", judgeCount); // 1.5w } /** * Note: theoretically, a two-dimensional array should be created to represent the chessboard, but in fact, the problem can be solved by using a one-dimensional array through the algorithm * arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3} * The corresponding arr subscript indicates the row, that is, the queen, arr [i] = Val, Val indicates the I + 1st queen, which is placed in column val+1 of row i+1 */ // Define a max to indicate how many queens there are int max = 8;// Eight queens are placed on an 8 * 8 chessboard // Define the array array to save the results of the Queen's placement position, such as arr = {0, 4, 7, 5, 2, 6, 1, 3} int[] array = new int[max]; static int count = 0;// How many records are there and how they are placed static int judgeCount = 0;// Record how many times you judged /** * Write a method to place the nth queen. Pay special attention to: check means that there is for (int i = 0; I < max; I + +) in the check every time you recurse * So there will be backtracking * * @param n */ private void check(int n) { if (n == max) {// n = 8: n+1=9 queens, indicating that the first 8 queens have been placed print(); // Output the pendulum method for this case return;// end } // Put the queen in turn and judge whether there is conflict for (int i = 0; i < max; i++) { // First, put the current queen n in column (i+1) of the row array[n] = i; // Judge whether there is a conflict when placing the nth queen to column i if (judge(n)) { // No conflict // If there is no conflict, then put n+1 queens, that is, start recursion check(n + 1); // } // If there is a conflict, continue to execute array[n] = i; That is, the nth queen is placed in a position where the line has to be moved back } } /** * Judge that when we place the nth queen, we will detect whether the queen conflicts with the queen already placed in front * * @param n Represents the nth queen * @return */ private boolean judge(int n) { judgeCount++; for (int i = 0; i < n; i++) { // explain // 1. array[i] == array[n] means to judge whether the nth queen is in the same column as the previous n-1 queens // 2. Math.abs(n-i) == Math.abs(array[n] - array[i]) indicates whether the nth queen and the ith queen are in the same slash // N = 1 place column 2: 1 < --- > n = 1 array [1] = 1 // Math.abs(1-0) == 1 similarly, Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1 // 3. It is not necessary to judge whether it is on the same line, because n is increasing every time if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) { return false; } } return true; } // Write a method to output the position of the queen private void print() { count++; for (int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } System.out.println(); } }
Force buckle queen related topics
-
Title Link: Interview question 08.12. Eight queens,51. Queen n,52. N Queen II
-
Problem solving idea: backtracking method
-
Problem solving Code:
public class Test36 { public static void main(String[] args) { // Test max=4 System.out.println(new Test36().solveNQueens(4)); } public List<List<String>> solveNQueens(int max) { /** * Note: theoretically, a two-dimensional array should be created to represent the chessboard, but in fact, the problem can be solved by using a one-dimensional array through the algorithm * arr[8] = {0 , 4, 7, 5, 2, 6, 1, 3} * The corresponding arr subscript indicates the row, that is, the queen, arr [i] = Val, Val indicates the I + 1st queen, which is placed in column val+1 of row i+1 */ // Define a max to indicate how many queens there are int[] array = new int[max];// Max queens are placed on the max*max chessboard // Returned result set // eg: when there are 4 queens, output - > [. Q.... Q, Q....,.. Q.], [.. Q., Q..,... Q,. Q..]] List<List<String>> res = new ArrayList<>(); // Place the 0 (i.e. the first queen) and max queens at most. The two-dimensional chessboard represented by the one-dimensional array array needs to return the result set check(0, max, array, res); return res; } /** * Backtracking method: place the nth queen * @param n Place the n+1 Queen (n starts from 0) * @param max Place max queens * @param array Two dimensional chessboard represented by one-dimensional array array * @param res Result set to return */ private void check(int n, int max, int[] array, List<List<String>> res) { if (n == max) { // n+1 queens have been placed, indicating that the first n queens have been placed List<String> list = print(array);// Store the pendulum method of this case in list < string > res.add(list);// Store the pendulum method in this case into the result set list < list < string > > return;// end } // Put the queen in turn and judge whether there is conflict for (int i = 0; i < max; i++) { // First, put the current queen n in column (i+1) of the row array[n] = i;// The first queen places the nth column in turn after all conditions in the first row and the first column occur if (judge(n, array)) {// Judge whether there is a conflict when placing the nth queen to column i // If there is no conflict, then put n+1 queens, that is, start recursion check(n + 1, max, array, res); } // If there is a conflict, continue to execute array[n] = i; That is, the nth queen is placed in a position where the line has to be moved back } } /** * Judge whether there is conflict with the previous queen when placing the nth emperor * @param n * @param array * @return */ private boolean judge(int n, int[] array) { for (int i = 0; i < n; i++) { // explain // 1. array[i] == array[n] means to judge whether the nth queen is in the same column as the previous n-1 queens // 2. Math.abs(n-i) == Math.abs(array[n] - array[i]) indicates whether the nth queen and the ith queen are in the same slash // N = 1 place column 2: 1 < --- > n = 1 array [1] = 1 // Math.abs(1-0) == 1 similarly, Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1 // 3. It is not necessary to judge whether it is on the same line, because n is increasing every time if (array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n] - array[i])) { return false; } } return true; } /** * Save the placement method in a certain case into list < string > and return * @param array * @return */ private List<String> print(int[] array) { List<String> list = new ArrayList<String>(); for (int i = 0; i < array.length; i++) {// array = [1 3 0 2] String str = ""; for (int j = 0; j < array.length; j++) { if (j == array[i]) { str = str + "Q"; } else { str = str + "."; } } list.add(str); } return list; } }