Resource constraints

Time limit: 1.0s memory limit: 512.0MB

Problem description

Given an n*n chessboard, there are some positions in the chessboard that cannot put queens. Now put n black queens and n white queens into the chessboard, so that any two black queens are not in the same row, column or diagonal, and any two white queens are not in the same row, column or diagonal. How many kinds of playing methods are there altogether? N is less than or equal to 8.

Input format

The first line of input is an integer n, which represents the size of the chessboard.

In the next N lines, there are n integers of 0 or 1 in each line. If an integer is 1, it means that the corresponding position can be placed as Queen. If an integer is 0, it means that the corresponding position cannot be placed as Queen.

Output format

Output an integer indicating the total number of playback methods.

sample input

4

1 1 1 1

1 1 1 1

1 1 1 1

1 1 1 1

sample output

2

sample input

4

1 0 1 1

1 1 1 1

1 1 1 1

1 1 1 1

sample output

0

My analysis: there is really no big difference between Queen 2n (black and white) and queen n. let's start with queen n. Here, it requires the chessboard to place 0 and 1 randomly, so we still have to use a two-dimensional array to represent the chessboard. The array elements store 0 or 1, black or white. This problem is divided into two parts according to the classical algorithm, how to find and how to judge. How to find is how to traverse the whole chessboard to find and determine the position; How to judge is how to judge that the current position is "correct".

We can start from the first position, from left to right, from top to bottom. Because it is required that it cannot be in the same row, you can directly jump to the next row to find the position of the next row after finding the position in the current row. Because each line is retrieved from the first one and immediately jumps to the next line after finding it, there is no need to judge whether the same line has the same queen. We only need to judge the three red lines in the graph, namely column, left diagonal and right diagonal. Because of the search order from left to right and from top to bottom, we only judge the "first half", and the latter ones have not been searched, so there must be no same elements. That's how to judge. Next, think carefully about how to find it.

In the case of backtracking, it retrieves the wrong place and immediately returns to the previous line to change the position. For example, I have found row 3 now, but the position of each column conflicts with the position arranged above. At this time, we have to go back to row 2. Assuming that row 2 and column 4 are arranged before, so we just go back to (2, 4), and then move to the next position, that is (2, 5). We can't move forward, because the previous positions are inconsistent with the position above, So we can only move back. The positions behind are those that have not been retrieved. After each fallback, (2, 4) the original position will be changed back to 1, because it is no longer used by us, so it should be changed back to the original in time. In addition, when the black-and-white queens are placed, the count + + function also needs to fall back, and the position set back will become 1, because we have to find a new placement position, so this is necessary. At the beginning, I still had a doubt, black or white first, and the exchange of black and white positions is a new pendulum method. Isn't it that the final result has to be multiplied by 2? But the subtlety of backtracking solves these problems. Fallback is to go back from the back to the front. After all the possible positions in line 5 are found, it will go back to line 4 and be placed in a new position. In this way, it will go back to the position of the first row and the first column of the first row, and then move to (1, 2) and find a new position. In this case, suppose that we are white first, (1, 1) was occupied by white just now, and now the white is moved to (1, 2), Then the black one will have the opportunity to move to the position of (1, 1), so my previous concern is that the black-and-white position is interchanged and multiplied by 2, which is completely unnecessary. Backtracking is really violent. It traverses all possibilities to ensure the accuracy of our results. Here we stipulate that 2 means white queen and 3 means black queen.

import java.util.Scanner; public class Main { //Used to store chessboard static int[][] chessboard; //"Order" of chessboard static int n; //Types and times of Queen placement static int count; public static void main(String[] args) { Scanner in = new Scanner(System.in); n = in.nextInt(); chessboard = new int[n][n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) chessboard[i][j] = in.nextInt(); //The default is to start from line 0 and find the white queen first dfs(0, 2); System.out.println(count); in.close(); } /** * Judge whether the current position can be put * @param x Row coordinates * @param y Column coordinates * @param type Is it white or black * @return */ public static boolean check(int x, int y, int type) { if (chessboard[x][y] != 1) return false; //Judge whether there is the same queen on the current column for (int i = 0; i < x; i++) if (chessboard[i][y] == type) return false; //Determine whether there are the same elements on the right diagonal for (int i = x - 1, j = y + 1; i > -1 && j < n; i--, j++) if (chessboard[i][j] == type) return false; //Determine whether there are the same elements on the left diagonal for (int i = x - 1, j = y - 1; i > -1 && j > -1; i--, j--) if (chessboard[i][j] == type) return false; return true; } /** * The placement position can be regarded as finding a "path". If the current position is not good, go back and use dfs (backtracking method) * @param row Number of lines on the chessboard * @param type 2 Indicates the White Queen and 3 indicates the black queen */ public static void dfs(int row, int type) { //Last line judgment if (row == n) { if (type == 2) //If the White Queen determines the position, she will start to put the black queen in the position dfs(0, 3); else//If the black queen arranges it, the number will be increased by 1 count++; return; } //i represents the number of columns, and the number of rows increases recursively for (int i = 0; i < n; i++) if (check(row, i, type)) { chessboard[row][i] = type; //When this line is found, go directly to the next line dfs(row + 1, type); //Go back here after searching, and this position will become the same, in order to find a new placement position chessboard[row][i] = 1; } } }