洛谷P1219八皇后(正向暴力递归dfs+回溯更新,全排列类型题)

题目链接:https://www.luogu.org/problemnew/show/P1219

这题就是搜索递归dfs+回溯更新,有多个标记数组。

难点在于:怎样标记(列标记还好,对角线标记麻烦!),是关键。
注意怎样标记需要必须想出这个规律:主对角线相减为定值(相减可能为负数,所以统一加n不影响结果),次对角线相加为定值。到这题目就做出来了。

题目跟全排列比较像,属于一类题。

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 typedef unsigned long long ull;
 9 const int maxn=1e3+5;
10 const int inf=1e9;
11 int ans[maxn];
12 int vis[3][maxn];//vis[0][maxn]存列,vis[1][maxn]存左下到右上对角线,vis[2][maxn]存右下到左上对角线
13 int n,cnt;
14 
15 void so(int i)//i第几行
16 {
17     if(i>n)//递归出口,序列已经排好
18     {
19         cnt++;
20         if(cnt<=3)
21         {
22             for(int k=1;k<=n-1;k++) cout<<ans[k]<<' ';
23             cout<<ans[n]<<endl;
24         }
25         return;
26     }
27 
28     for(int j=1;j<=n;j++)
29     {
30         if(vis[0][j]==0 && vis[1][i-j+n]==0 && vis[2][i+j]==0)
31         {
32             vis[0][j]=1;
33             vis[1][i-j+n]=1;
34             vis[2][i+j]=1;
35 
36             ans[i]=j;
37             so(i+1);
38 
39             vis[0][j]=0;
40             vis[1][i-j+n]=0;
41             vis[2][i+j]=0;
42         }
43     }
44 }
45 
46 
47 int main()
48 {
49     ios::sync_with_stdio(false); cin.tie(0);
50 
51     cin>>n;
52 
53     so(1);
54 
55     cout<<cnt<<endl;
56 
57     return 0;
58 }

再附个全排列代码

全排列很简单,就是从小到大所有情况都来一遍,以3为例跟一遍代码就明白

 1 #include <iostream>
 2 #include <string>
 3 #include <algorithm>
 4 #include <cstdio>
 5 #include <cstring>
 6 using namespace std;
 7 typedef long long ll;
 8 typedef unsigned long long ull;
 9 const int maxn=1e3+5;
10 const int inf=1e9;
11 int ans[maxn];
12 int vis[maxn];//标记数组
13 int n,cnt;
14 
15 void so(int k)
16 {
17     if(k>n)
18     {
19         for(int i=1;i<=n-1;i++) cout<<ans[i]<<' ';
20         cout<<ans[n]<<endl;
21         return;
22     }
23 
24     for(int i=1;i<=n;i++)//i从1到n,只要有小的就用上,所以说一定是字典序从小到大的排列,每个排列都试一遍就成了全排列
25     {
26         if(vis[i]==0)
27         {
28             vis[i]=1;
29 
30             ans[k]=i;
31             so(k+1);
32 
33             vis[i]=0;
34         }
35     }
36 }
37 
38 
39 int main()
40 {
41     ios::sync_with_stdio(false); cin.tie(0);
42 
43     cin>>n;
44 
45     so(1);
46 
47     return 0;
48 }

完。

原文地址:https://www.cnblogs.com/redblackk/p/9744353.html