4 条题解
-
7
做这道题,我们要解决如下问题:
- 如何判断是否在 k 列 i 行可行?
- 放下一个皇后后,怎么让其所在行,列,两条斜线都不能再次放置另一个皇后?
- 如果某一列的每一行都无法再次放置皇后,要怎么回溯到上一次?
- 如果k==8时,输出一个可行解后怎么在查找下一个可行解?
- -最后我们要怎么退出?
A. 对于①、②问题,我们先要找到一种方式来储存可行解,当然我们也可以用二维数组来模拟棋盘,每放置一个皇后就把这位置标记下来,并把所在行列斜线都标记为false,再进行下一次放置皇后时,根据该行该列是否是 false 来放置。但自习思考这样会造成标记和输出上的麻烦 。为了使问题便于思考和简化代码,我们可以采取以下方法。
- 用一维数组 col[9] 来表示每列上皇放置的位置,如row[A]=B:代表第 A 列第9行放置了一个皇后。
- 用 bool row[9],digLeft[16],digRight [16]分别表示每行,左低右高线和右低左高线上是否被禁止放置皇后。如row[A]=false,digLeft[B]=false,digRight[C]=false,表示第 A 行,第B条左低斜线和第C条右高斜线上不能放置皇后。至于列就不用了管它了。通过规律我们可以把 B 和 C 用 k 和 i 表示出来。
B. 对于③,但循环 i=9 时自然会退出回溯到上一次放置皇后,不过我们要额外加一条代码来取消上一次的标记。对于④也是同理。
C. 当我们把所有能够试探的方法试探玩后,k=9,自然就会退出递归。
一切都思考清楚后就可以释放代码了,奥利给!
AC代码
#include <iostream> using namespace std; void queen_all(int k,int n); int col[100]={0},times=0; //用times来记录一共多少种结果 bool row[100]={0},digLeft[100]={0},digRight[100]={0}; int main() { int n=0; cin>>n; queen_all(1,n); cout<<times; return 0; } void queen_all(int k,int n) { int i=0; for (i=1;i<=n;++i) { if (row[i]!=1&&digLeft[k+i-1]!=1&&digRight[n+k-i]!=1) { col[k]=i; row[i]=digLeft[k+i-1]=digRight[n+k-i]=1; if (k==n) { for (int j=1;j<=n;++j) cout<<col[j]<<' '; cout<<endl; ++times; } else queen_all(k+1,n); row[i]=digLeft[k+i-1]=digRight[n+k-i]=0; } } }
-
0
xyz表示竖列和两个斜列,话说为什么数据范围6~10会有10个样例啊(
#include<bits/stdc++.h> using namespace std; bool x[20],y[50],z[50]; int n,a[17],ans; void dfs(int d) { if (d==n+1) { for (int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<'\n'; ans++; return; } for (int i=1;i<=n;i++) if (!x[i]&&!y[i+d]&&!z[i-d+n]) { x[i]=1,y[i+d]=1,z[i-d+n]=1; a[d]=i; dfs(d+1); x[i]=0,y[i+d]=0,z[i-d+n]=0; } } int main() { cin>>n; dfs(1); cout<<ans; return 0; }
-
-1
#include<bits/stdc++.h> using namespace std; // total表示方案数,a[i]表示第i行摆放了棋子的位置 // b[i]、c[i]、d[i]表示当前列、对角线上摆放了棋子的位置 int n,total,a[25],b[25],c[25],d[25]; void dfs(int i){ if(i>n){ // i>n说明搜索到了第n+1行,此时已经找到一个方案 for(int j=1;j<=n;j++) cout<<a[j]<<" "; cout<<"\n"; total++; return; } for(int j=1;j<=n;j++) if(a[i]==0&&b[j]==0&&c[i+j]==0&&d[i-j+n]==0){ // 满足不重复时 a[i]=b[j]=c[i+j]=d[i-j+n]=j; // 记录当前位置 dfs(i+1); // 递归调用搜索下一行 a[i]=b[j]=c[i+j]=d[i-j+n]=0; // 回溯 } } int main(){ ios::sync_with_stdio(false); // 输入输出加速 cin.tie(0); cout.tie(0); cin>>n; dfs(1); // 由第1行开始搜索 cout<<total; return 0; }
-
-1
#include <bits/stdc++.h> using namespace std; int n, ans, a[100]; bool vis1[100], vis2[100], vis3[100]; void dfs(int step) { if (step == n + 1) { ans++; for (int i = 1; i <= n; i++) { cout << a[i] << " "; } cout << endl; return; } for (int i = 1; i <= n; i++) { if (!vis1[i] && !vis2[i - step + 15] && !vis3[i + step]) { vis1[i] = 1, vis2[i - step + 15] = 1, vis3[i + step] = 1; a[step] = i; dfs(step + 1); vis1[i] = 0, vis2[i - step + 15] = 0, vis3[i + step] = 0; } } } int main() { cin >> n; dfs(1); cout << ans; return 0; }
- 1
信息
- ID
- 1912
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 174
- 已通过
- 95
- 上传者