dfs-Eight Queens

dfs- Eight Queens

Source: Luogu p1219

Title description

A 6×6 checker board is as follows. There are six chess pieces placed on the board, so that there is one and only one in each row and column, and on each diagonal (including all parallel lines of the two main diagonals) There is at most one chess piece.

img

The above layout can use the sequence
2 4 6 1 3 5 2\ 4\ 6\ 1\ 3\ 52 4 6 1 3 5     
to describe, the i-th number indicates that there is a pawn in the corresponding position of the i-th row, as follows:

Line number:
1 2 3 4 5 6 1\ 2\ 3\ 4\ 5\ 61 2 3 4 5 6     
Column number:
2 4 6 1 3 5 2\ 4\ 6\ 1\ 3\ 52 4 6 1 3 5     
This is just a solution for the placement of the pieces. Please make a program to find the solution of all the chess pieces.
And output them in the above sequence method, and the solutions are arranged in lexicographic order.
Please output the first 3 solutions. The last line is the total number of solutions.

Input format

A positive integer n on a line indicates that the chessboard is n × n in size.

Output format

The first three lines are the first three solutions, and the two numbers in each solution are separated by a space. There is only one number in the fourth line, which indicates the total number of solutions.

Sample input and output

Enter #1

6

Output #1

2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

The main idea is (backtracking):

Assuming that the queen can now be placed at the xth position of the nth row, I tentatively put a queen at this position, and then record the corresponding rows, columns, and diagonals as unavailable.

Then to the n+1th row, if you can find a place to place the queen in the n+1th row, continue to look down (the n+1th row, the n+2th row... only what you find). If you can't find it, move the position of the queen in the nth row to the next position in the nth row where the queen can be placed, and continue to look down.

Specific operation:

1: Use the sat[15] array to record the position of the queen. The subscript of sat is the row by default, and the value of sat is the corresponding column. For example, sat[0]=4, that is, there is a queen in the fourth position of the first row

2: I chose three arrays to represent the state of the chessboard (that is, whether the row, column, and diagonal are available). They are lr[15] from the bottom left to the top right diagonal (parallel lines), and rl[15] starts from The diagonal line (parallel line) from the bottom right to the top left, l[15] judges whether the column is available; (There is no judgement line here, because our queen is placed on the previous line and then goes to the next line to find it, so it does not exist The problem that the line cannot be used)

3: At this time, how to express the relationship between the diagonal and the ranks has become the main problem I want to solve, and then I found the diagonal lines from the bottom left to the top right (diagonal parallel lines) such as 31 22 13 and 41 32 23 14. The sum of the ranks is equal to a fixed value, and is equal to the sum of the ranks.

The lower right to the upper left is also a regular value of the row minus column is fixed , in order to ensure the array index is positive, so we add the line minus n on the basis of the column.

11 12 13 14
21 22 23 23
31 32 33 34
41 42 43 44

There should be no problem now. Then I handed in a serve, it was WA hahahaha.

I found that the array is too small. For an n*n chessboard, the number of diagonals is much larger than n. lr[15] will inevitably cross the boundary. . . (Or to explain, lr[] is used to determine whether each diagonal (parallel line) from the bottom left to the top right of the chessboard is available. 0 is available, 1 is not! It's wordy )

Then change to lr[40] to AC~

On the code:

#include<bits/stdc++.h>
using namespace std;
int n,res=0;//n为棋盘大小,res为最终结果数 
int sat[15];//sat的下标默认为行,sat的值是对应列,例如sat[0]=4,即为在第一行的第四个位置存在一个皇后
int lr[40],rl[40],l[40];//lr表示从左下到右上的对角线,rl表示从右下到左上的对角线,l记录某列是否可用 
void dfs(int a)
{
    
    
	if(a>n) //n行都走遍了,深搜完毕 
	{
    
    
		res++;//又一种情况满足条件 
		if(res<=3){
    
    //输出字典序列的前三种情况 
			for(int i=1;i<=n;i++)
			{
    
    
				printf("%d ",sat[i]);
			}
			printf("\n");
			return ;
		}
		else return;
    }
		 
		//每一行的每个位置都试探一下 
		for(int j=1;j<=n;j++)
		{
    
    
		    if(l[j]==0&&lr[a+j]==0&&rl[a-j+n]==0)
		    {
    
    
		    	l[j]=1;//该列被记录
				lr[a+j]=1;//该条对角线被记录
				rl[a-j+n]=1;//该条右下到左上的对角线被记录
				sat[a]=j;//第a行皇后的位置是j
				
				dfs(a+1);//下一行搜索
				l[j]=lr[a+j]=rl[a-j+n]=0;//回溯 
			}
		} 
}
int main (){
    
    
	scanf("%d",&n);
	dfs(1);
	printf("%d\n",res);
	return 0; 
}

Insert picture description here
Welcome to leave a friendly comment, where is the problem dd me.

Guess you like

Origin blog.csdn.net/m0_46288176/article/details/109233936