洛谷的一道类似的n皇后题:P1219 八皇后
题目:n皇后问题
Description
在n×n 格的棋盘上放置彼此不受攻击的n 个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何两个皇后不放在同一行或同一列或同一斜线上。
设计一个解n皇后问题的队列式分支限界法,计算在n×n个方格上放置彼此不受攻击的n个皇后的一个放置方案。
注意,本问题的答案可能是不唯一的。如,当n=5时,至少有3个答案:
Input
输入一行,一个正整数n。 4 < n < 13
Output
输出彼此不受攻击的n个皇后的一个放置方案。
Sample Input
5
Sample Output
1 3 5 2 4
#include<iostream>
using namespace std;
///用四个数组分别去标记行,列,斜上,斜下,注意斜上和斜下的数组要开成行列数组的两倍
bool hang[15],lie[15],xieshang[30],xiexia[30];
int ans[15],k,n,sum;
void dfs(int i)
{
if(sum==1)return; ///当已经搜索到一个方案后,便会一直放回到主函数,不再搜索下去了
if(i==n+1){
for(int d=1;d<=k;d++)cout<<ans[d]<<' ';
cout<<endl;
sum++;
return;
}
for(int j=1;j<=n;j++){
if((!hang[i])&&(!lie[j])&&(!xieshang[i+j-1])&&(!xiexia[i-j+n])){
hang[i]=1,lie[j]=1,xieshang[i+j-1]=1,xiexia[i-j+n]=1;
ans[++k]=j;
dfs(i+1);
k--;
hang[i]=0,lie[j]=0,xieshang[i+j-1]=0,xiexia[i-j+n]=0;
}
}
return;
}
int main()
{
cin>>n;
dfs(1);
//cout<<sum<<endl; 此时这里的输出结果是sum=1
return 0;
}
题目:2n皇后问题
Description
给定一个n×n ( 0 < n ≤ 8 )的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?
Input
多测试用例,每个测试用例:
第一行为一个整数n,表示棋盘的大小。
接下来n行,每行n个0或1的整数。
如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
Output
每个测试用例输出一行:一个整数,表示总共有多少种放法。
Sample Input
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
Sample Output
2
0
分析:
先放完一种颜色的皇后之后再去放另一种颜色的皇后(如:先放完白皇后之后再去放黑皇后),做法是在n皇后的基础上再加一个dfs去搜索另一颜色皇后的摆放方法就行了。
代码如下:
#include<iostream>
using namespace std;
bool hang[10],lie[10],xieshang[20],xiexia[20];///白皇后的四个方向标记数组
bool hang2[10],lie2[10],xieshang2[20],xiexia2[20]; ///黑皇后的四个方向标记数组
int G[10][10],n,sum;
void dfs_black(int i)///黑皇后
{
if(i==n+1){
sum++;
return;
}
for(int j=1;j<=n;j++){
if((!hang2[i])&&(!lie2[j])&&(!xieshang2[i+j-1])&&(!xiexia2[i-j+n])&&G[i][j]){
hang2[i]=1,lie2[j]=1,xieshang2[i+j-1]=1,xiexia2[i-j+n]=1;
dfs_black(i+1);
hang2[i]=0,lie2[j]=0,xieshang2[i+j-1]=0,xiexia2[i-j+n]=0;
}
}
return;
}
void dfs_white(int i)///白皇后
{
if(i==n+1){
/*白皇后摆放完之后再去摆放黑皇后*/
dfs_black(1);
return;
}
for(int j=1;j<=n;j++){
if((!hang[i])&&(!lie[j])&&(!xieshang[i+j-1])&&(!xiexia[i-j+n])&&G[i][j]){
hang[i]=1,lie[j]=1,xieshang[i+j-1]=1,xiexia[i-j+n]=1;
G[i][j]=0;///表示该位置已被白皇后摆放,之后摆放黑皇后就不能再摆放在该位置
dfs_white(i+1);
G[i][j]=1;
hang[i]=0,lie[j]=0,xieshang[i+j-1]=0,xiexia[i-j+n]=0;
}
}
return;
}
int main()
{
ios::sync_with_stdio(false);
while(!(cin>>n).eof())
{
sum=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>G[i][j];
dfs_white(1);///先摆放白皇后
cout<<sum<<endl;
}
return 0;
}