2n皇后问题
问题描述
给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
输入格式
输入的第一行为一个整数n,表示棋盘的大小。
接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。
输出格式
输出一个整数,表示总共有多少种放法。
样例输入
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
2
样例输入
4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1
样例输出
0
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int a[11],b[11],n,countt,f[11][11];//a[]括号里代表所在行
void dfs2(int x)
{
if(x == n+1)
{
countt++;
return;
}
for(int i = 1; i <= n; i++)
{
if(f[x][i]==0||a[x]==i)continue;
b[x] = i;
int flag = 1;
for(int j = 1; j < x; j++)
{
if(b[j]==i||abs(b[j]-i)==x-j)
{
flag = 0;break;
}
}
if(flag)
{
dfs2(x+1);
}
}
}
void dfs1(int x)
{
if(x == n+1)
{
dfs2(1);
return;
}
for(int i = 1; i <= n; i++)
{
if(f[x][i]==0)continue;
a[x] = i;
int flag = 1;
for(int j = 1; j < x; j++)
{
if(a[j]==i||abs(a[j]-i)==x-j)
{
flag = 0;break;
}
}
if(flag)
dfs1(x+1);
}
}
int main()
{
int i, j;
while(scanf("%d",&n)!=-1)
{
countt = 0;
memset(a,0,sizeof(int));
memset(b,0,sizeof(int));
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
scanf("%d",&f[i][j]);
}
}
dfs1(1);
printf("%d\n",countt);
}
return 0;
}