2n皇后
思路
类似于八皇后问题,我们还是一行一行去搜索,只不过八皇后只需放置一种棋子,此题在放完一种棋子后我们可以回到第一行开始第二轮放置。
//c==1表示现在放置的是第一种棋子,c==2表示现在放置的是第二个棋子
void dfs(int h, int c) {
if(h==n+1&&c==2) {
ans++;
return ;
}
if(h==n+1) {
dfs(1,c+1);
}
for(int i=1; i<=n; i++) {
if(!vis[h][i]&&v[i]!=3&&v[i]!=c&&v1[h+i]!=3&&v1[h+i]!=c&&v2[h-i+n]!=3&&v2[h-i+n]!=c) {
vis[h][i]= true;
v[i]+=c;
v1[h+i]+=c;
v2[h-i+n]+=c;
dfs(h+1,c);
vis[h][i]= false;
v[i]-=c;
v1[h+i]-=c;
v2[h-i+n]-=c;
}
}
}
bool vis[20][20];//TRUE当前位置不能再放置棋子
int v[15],v1[20],v2[20];
//v[15]表示列: 0:两种都可放 1:这列第一种不可放 3:都不可放
//v1,v2两条对角线:0:两种都可放 1:这列第一种不可放 3:都不可放
完整代码
#include<bits/stdc++.h>
using namespace std;
int s[20][20];
bool vis[20][20];
int v[15],v1[20],v2[20];
int n;
int ans = 0;
void dfs(int h, int c) {
if(h==n+1&&c==2) {
ans++;
return ;
}
if(h==n+1) {
dfs(1,c+1);
}
for(int i=1; i<=n; i++) {
if(!vis[h][i]&&v[i]!=3&&v[i]!=c&&v1[h+i]!=3&&v1[h+i]!=c&&v2[h-i+n]!=3&&v2[h-i+n]!=c) {
vis[h][i]= true;
v[i]+=c;
v1[h+i]+=c;
v2[h-i+n]+=c;
dfs(h+1,c);
vis[h][i]= false;
v[i]-=c;
v1[h+i]-=c;
v2[h-i+n]-=c;
}
}
}
int main() {
scanf("%d",&n);
for(int i = 1; i <= n; i++) {
for(int j = 1; j<=n; j++) {
scanf("%d",&s[i][j]);
if(s[i][j]==0) {
vis[i][j]=true;
}
}
}
//dfs(n,m)m==1,黑,m==2,白
dfs(1,1);
printf("%d\n",ans);
return 0;
}