基础练习 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
代码解释:
(abs(j-k)==abs(i-hei[j]))
在一条斜线上即使行差距与列差距相等
#include<stdio.h>
#include<math.h>
void xiaqi(int x,int k);
int sum=0;//记录有多少种方法
int n;
int hei[10],bai[10];//存储白棋/黑棋位置,以下标为行数,值为列数
int luozi[10][10];//存储棋盘
int main(void)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&luozi[i][j]);
}
}
xiaqi(1,1);
printf("%d",sum);
}
void xiaqi(int x,int k)
{
if(k>n)
{
sum++;
return;
}
for(int i=1;i<=n;i++)//将第k行的皇后放到第i个列上
{
if(luozi[k][i]==0)//判断棋盘是否可以落子
continue;
if(x==1)//黑皇后
{
int isFight=0;
for(int j=1;j<k;j++)//将第k行的皇后与已经放置的第j个黑皇后比对
{
if(i==hei[j] || (abs(j-k)==abs(i-hei[j])))//判断是否起冲突
{
isFight=1;
break;
}
}
if(isFight)//起冲突,放置下一个
{
continue;
}else{
hei[k]=i;
xiaqi(2,k);//放置对应的白皇后
}
}else{//白皇后
if(i==hei[k])//判断是否已有黑皇后
continue;
int isFight=0;
for(int j=1;j<k;j++)//将第k行的皇后与已经放置的第j个白皇后比对
{
if(i==bai[j] || (abs(j-k)==abs(i-bai[j])))//判断是否起冲突
{
isFight=1;
break;
}
}
if(isFight)//起冲突,放置下一个
{
continue;
}else{
bai[k]=i;
xiaqi(1,k+1);//放置对应的黑棋
}
}
}
}