AcWing 843. n-皇后问题 状态压缩优化
原题链接
中等
作者:
ZeroAC
,
2020-03-04 12:51:09
,
所有人可见
,
阅读 1876
//y总版本
#include<bits/stdc++.h>
using namespace std;
const int N = 15;
char g[N][N];//所填的
int n;
bool col[N],gd[N*2],rgd[N*2];//列占用,对角占用 反对角占用
void dfs(int u){//从下标为u行开始搜索
if(u==n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++) cout<<g[i][j];
cout<<endl;
}
cout<<endl;
}
for(int j = 0; j < n; j++){//计算u行的皇后应该放在哪一列
if(!col[j]&&!gd[j-u+n]&&!rgd[u+j]){
g[u][j] = 'Q';
col[j] = 1, gd[j-u+n] = 1,rgd[u+j] = 1;//占用两个对角线
dfs(u+1);
g[u][j] = '.';
col[j] = 0, gd[j-u+n] = 0,rgd[u+j] = 0;//占用两个对角线
}
}
}
int main(){
cin>>n;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++) g[i][j] = '.';
}
dfs(0);
return 0;
}
//位运算状态压缩优化
#include<bits/stdc++.h>
using namespace std;
const int N = 10;
bool g[N][N];
int n;
/*
用三个整型变量来表示状态 c-列放置情况 d-对角线放置情况 rd-反对角线放置情况 其中1代表此处有皇后了
从左到右为 低位->高位
例如 对于c状态 当前为 1 0 0
若填了 j = 1 位 下一c状态为 1 1 0 即为 c|(1<<j)
对于d状态 当前为 0 0 1
若填了 j = 1 位 则首先变为 0 1 1
下一c状态为 0 0 1 1 即为 (d|(1<<j))<<1
对于rd状态 当前为 1 0 1
若填了 j = 1 位 则首先变为 1 1 1
下一c状态为 1 1 0 即为 (d|(1<<j))>>1
*/
void dfs(int k, int c, int d, int rd){//尝试放第k行的皇后 此时的状态为 c - 列 d - 对角 rd - 反对角
if(k==n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
if(g[i][j]) cout<<"Q";
else cout<<".";
}
cout<<endl;
}
cout<<endl;
}
int ban = c|d|rd;//不能填的位置
for(int j = 0; j < n; j++){
if(ban&(1<<j)) continue;//此处不能放皇后
g[k][j] = true;
dfs(k+1, c|(1<<j), (d|(1<<j))<<1, (rd|(1<<j))>>1);
g[k][j] = false;
}
}
int main(){
cin>>n;
dfs(0,0,0,0);
return 0;
}
第一个dfs函数没返回
感谢
为什么状态压缩的对角线是这样更新的呢
注释很清楚,但好像有点写错: