P1219 Eight Queens (dfs + thinking)

Insert picture description here
Insert picture description here
The meaning of the question: There are n n grids, and then there can be at most 1 queen (meaning there can be 0 or 1) on the extension line in any one of the 8 directions of a point
. Graph understanding: For
example
The 6-6 grid on the title ;
then there are:
Insert picture description here
these 8 directions; at most one queen appears on each color line, ask how many different schemes of putting queens in total (referring to the patterns formed by the schemes will not be exactly the same) ;
Now the meaning of the question is clear;
then the difficulty of this question is how to judge whether this point can be walked (is there already a queen in 8 directions)? How should I go?
This problem can be found by looking for a rule:
1. For a yellow line slanting to the right, the x coordinate + y coordinate on each grid is a fixed value; so the line parallel to the yellow line has the same rule;
2. For For the blue line slanting to the left, the x-y coordinate on each grid is a fixed value; so the line parallel to the blue line also has the same rule;
3. Each row and each column can have at most 1 queen, then I can enumerate whether each column is to put or not to put the queen, and then search the corresponding column in dfs, and then put
it after confirming that the position is legal; but there is a flaw in the problem of 2 that xy may be a negative number, so Here you can give him +n (actually + a large positive integer is also OK, but the array will be larger);
so this question has an idea; enumerate each column, then dfs enumerate the rows, after confirming the columns and rows , You can judge whether the 8 directions are legal; I was worried about TLE at first, but it is rare to write by hand, because the 8 directions are restricted; so it will not be n
!; AC code:

#include<bits/stdc++.h>
using namespace std;
int n;
int r[2000],ma[5200],sa[5000];//分别用来判断是否行合法,主对角是否合法,负对角是否合法
int ans[20];//记录排列答案
int t;
void dfs(int queen){
    
    //这里参数为什么是queen是因为这里的queen就相当与x坐标,因为每一列都必须有一个皇后,所以参数传这里
	if(queen==n+1){
    
    
	  if(t<3){
    
    
	  	  for(int i=1;i<=n;i++)printf("%d%c",ans[i],i==n?'\n':' ');//按照dfs求全排列可以知道前三个就是字典序最小的,所以没有必要求出总的排列然后再去求字典序最小的
	  }
	  t++;
	  return ;	
	}
	for(int y=1;y<=n;y++){
    
    
		if(!r[y]&&!ma[queen+y]&&!sa[queen-y+n]){
    
    //第y行可以放并且主对角,副对角也可以放
			 r[y]=ma[queen+y]=sa[queen-y+n]=1;//标记已经放过了
			 ans[queen]=y;//在queen列上面的y行放一个
			 dfs(queen+1);//判断下一行是否能够放
     		r[y]=ma[queen+y]=sa[queen-y+n]=0;//撤销标记
		}
	}
}
int main(){
    
    
   scanf("%d",&n);
    dfs(1);//从第一列开始
    printf("%d\n",t);
	return 0;
} 

Guess you like

Origin blog.csdn.net/qq_44555205/article/details/104128109