(蓝桥杯)基础练习BASIC-27 2n皇后问题 (递归) C++

问题描述

  给定一个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

解题思路:首先使用二维数组建立棋盘,在分别定义数组w[maxn]存储白皇后落子情况,b[maxn]存储黑皇后落子情况例如w[3]=1意为白皇后在第三行的落子位置为第一列。逐行递归的落子,每次判断当前落子位置所在的竖列,对角线上是否已有落子,若有则条件不成立,无法落子,进入下一列;若条件成立,则进入下一行,直至完成棋盘遍历,确定最后结果。

对角线的计算方式:数学中的(x1-x2)/(y1-y2)计算斜率,计算结果为1或-1时,对角线倾斜45度/135度,代码中abs();函数作用为计算绝对值

#include
#include
#include
#define maxn 10
int chess[maxn][maxn];//棋盘 
int w[maxn],b[maxn],n,result=0;//w[maxn]存储白皇后落子情况,b[maxn]存储黑皇后落子情况 
/*检查是否符合落子规则*/ 
bool check(char c,int x){
	char color=c;
	int row=x;
	//若为白皇后,则检查其所在横排、竖列或对角线上是否有同色落子 
	if(color=='w'){
		for(int i=1;in){
		//满足题意,result值+1 
		result++;
	}
	for(int i=1;i<=n;i++){
		if(chess[x][i]==1&&w[x]!=i){
			b[x]=i;
			//检查结果若为真,则落子 
			if(check('b',x)){
				queen_b(x+1);
			}
		}
	}
}
/*白皇后落子(先)*/ 
queen_w(int row){
	int x=row;
	//白皇后落满,黑黄后开始落子 
	if(x>n){
		queen_b(1);
	}
	for(int i=1;i<=n;i++){
		if(chess[x][i]==1){
			w[x]=i;
			//检查结果若为真,则落子
			if(check('w',x)){
				queen_w(x+1);
			}
		}
	}
}

int main(){
	memset(w,0,sizeof(w));
	memset(b,0,sizeof(b));
	memset(chess,0,sizeof(chess));
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			scanf("%d",&chess[i][j]);
		}
	}
	//白皇后先落子,将对应的横行作为参数传递给函数 
	queen_w(1);
	printf("%d",result);
	return 0;
}

你可能感兴趣的:(算法/数据结构,蓝桥杯,2n皇后问题,递归,c++)