1 条题解
-
1
一道比较复杂的深搜。
首先我们用数组记录每个空的位置,然后从第一个空的位置开始搜,每填完一个空就转入下一个空的位置继续填……直到填完所有空。
接下来是标记的问题,标记与八皇后类似:开四个二维数组分别表示行、列和两条斜线上对应的数字是否使用过。例如 表示在第 行是否使用过数字 。
行列的标记很简单,斜线的标记复杂一些:通过观察发现,从左下到右上的斜线上的位置的行列坐标和是一定的,我们可以用 表示这样一条斜线的编号。而从左上到右下的斜线上的位置的行列坐标差是一定的,我们可以用 表示这样一条斜线的编号, 是为了防止负数。
可以画个矩阵理解标记,具体详见代码:
#include <bits/stdc++.h> using namespace std; int n,ans; char ch; bool h[10][10],l[10][10],c[11][10],d[18][10]; vector<int> x,y; void dfs(int id){ //当前正在填第id个空 if (id==x.size()){ ans++; return; //填写完毕,统计方案 } int X=x[id],Y=y[id]; for (int i=1;i<=n;i++){ if (!h[X][i]&&!l[Y][i]&&!c[X+Y][i]&&!d[X-Y+n][i]){ h[X][i]=1; l[Y][i]=1; c[X+Y][i]=1; d[X-Y+n][i]=1; dfs(id+1); h[X][i]=0; l[Y][i]=0; c[X+Y][i]=0; d[X-Y+n][i]=0; //又是一堆标记。。。。 } } } int main(){ cin>>n; for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ cin>>ch; if (ch=='*'){ //记录每个空的位置 x.push_back(i); y.push_back(j); continue; } h[i][ch-'0']=1; l[j][ch-'0']=1; c[i+j][ch-'0']=1; d[i-j+n][ch-'0']=1; //一堆标记。。。 } } dfs(0); cout<<ans; return 0; }
- 1
信息
- ID
- 688
- 时间
- 1000ms
- 内存
- 16MiB
- 难度
- 3
- 标签
- 递交数
- 28
- 已通过
- 19
- 上传者