ACWing843. n-皇后问题

题目

分析一

本问题可以按照全排列的dfs来写。生成一个排列数,下标 i 对应第 i 行,其上的数字代表放哪一列。

代码

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N = 20;//这里开到20
 5 bool col[N],dg[N],udg[N];
 6 char path[N][N];
 7 int n;
 8 
 9 void dfs(int u){
10     if(u == n){
11         for(int i = 0;i < n;i++){
12             puts(path[i]);  //直接按照一行输出
13         }
14         puts("");
15         return;
16     }
17     //遍历列,查看u行放哪一列
18     for(int i = 0;i < n;i++){
19         if(!col[i] && !dg[u+i] && !udg[n+i-u]){
20             path[u][i] = 'Q';
21             col[i] = dg[u+i] = udg[n+i-u] = true;
22             dfs(u+1);
23             path[u][i] = '.';
24             col[i] = dg[u+i] = udg[n+i-u] = false;
25         }
26     }
27     
28 }
29 int main(){
30     cin>>n;
31     for(int i = 0;i < n;i ++){
32         for(int j = 0;j < n;j++){
33             path[i][j] = '.';
34         }
35     }
36     dfs(0);
37     return 0;
38 }

上面代码 u 表示遍历行,i 表示遍历列

技巧:

1.主对角线标记数组dg。按照 y总说法将其按照直角坐标理解记忆:

主对角线方程:y = -x + b,副对角线方程:y = x + b

进而得到,主:y + x = b,副:y - x = b。对应代码 主:i + u = b ,副: i - u = b,而b是一定的。所以判断是否位于主对对角线或副对角线。只需看 i+u 或 i - u是否被访问过。这里对于副对角线的i-u还要加上偏移量n,这是因为减法会为负数,n - i + u  = n + b 等式不变,依然能表示副对角线。

2. 对于二维字符数组,用puts可直接打印一行

3. 为什么const int N 要开到 20,因为主、副对角线的访问数组 是 x + y ,而 x 的下标就是1—9

 分析二(按照位置坐标搜素)

代码

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 const int N = 20;
 5 bool row[N],col[N],dg[N],udg[N];
 6 char path[N][N];
 7 int n;
 8 
 9 //x,y表示坐标,s表示已经放入的皇后数量
10 //每一行开始遍历
11 void dfs(int x,int y ,int s){
12     if(y == n) y = 0,x++; //走到有边界,回来   这里不要dfs(x+1,0,s),因为 x 可能本身就为 n ,超出内存 改为:{dfs(x+1,0,s);return;} 
13     //行遍历结束
14     if(x == n){
15         //查看是否放了n个皇后
16         if(s == n){
17             for(int i = 0;i < n;i++){
18                 puts(path[i]);
19             }
20             puts("");
21         }
22         return;
23     }
24     
25     //该位置不放皇后
26     dfs(x,y+1,s);
27     
28     //该位置放皇后
29     if(!row[x] && !col[y] && !dg[x+y] && !udg[x-y+n]){
30         path[x][y] = 'Q';
31         row[x] = col[y] = dg[x+y] = udg[x-y+n] = true;
32         dfs(x,y+1,s+1);
33         path[x][y] = '.';
34         row[x] = col[y] = dg[x+y] = udg[x-y+n] = false;
35     }
36 }
37 
38 int main(){
39     cin>>n;
40     for(int i = 0;i < n;i ++){
41         for(int j = 0;j < n;j++){
42             path[i][j] = '.';
43         }
44     }
45     dfs(0,0,0);
46     return 0;
47 }
原文地址:https://www.cnblogs.com/fresh-coder/p/14429063.html