蓝桥杯每日一练之2n皇后问题

168 阅读2分钟

「这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战

💛作者主页:静Yu

🧡简介:CSDN全栈优质创作者、华为云享专家、前端知识交流社区创建者

💛社区地址:bbs.csdn.net/forums/Jing…

第十三届蓝桥杯大赛个人赛省赛比赛将于2022年4月9日(星期六)举办,趁现在寒假的时间抓紧时间备战一下。因为博主本人报名是C/C++组,所以更新所有内容都是C/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

解题思路:

本题目的求解思路是先求解出n皇后,再用同样的方式求解出2n皇后。题目给出了黑白皇后,顺序不重要,先放黑的话就在放白皇后,先放白的就再放黑的。主函数非常简单就是输入第一行数和循环输入下边的矩阵。最主要的内容就是皇后的位置判断,同行同列不能有重复的数字,如果同斜线,行号-列号之差绝对值相等说明在同一条对角线上。按照这种思路完成代码即可。 完整代码:

#include<iostream>
using namespace std;
int sum=0,n;
int a[10][10];
void huanghou(int i,int m){
	for(int j=0;j<n;j++){
		if(a[i][j]!=1){   //只要是不为1,其他数字都不能添加皇后,直接跳出 
			continue;
		} 
		int x=j-1,y=j+1,z=1,k; 
		for(k=i-1;k>=0;k--){    
			if(a[k][j]==m || x>=0 && a[k][x]==m || y<n && a[k][y]==m){
				z=0;         //本题从上往下遍历,同一行的可以不用检测,还没有到达的行也不用检测,只需要检测同一列和左右上角就行
				break;
			}   //如果出现皇后则不符题意,直接跳出,不执行下述步骤
			x--;y++;
		}
		if(z){
			a[i][j]=m;
			if(i!=(n-1)){
				huanghou(i+1,m);   //矩阵从零开始存储数据,当i=n-1时说明黑皇后已经放完,可以放白皇后了
			}
			else{
				if(m==2){
					huanghou(0,3);
				}
				else{
					sum++;    //当白皇后放完则表示一种放法
				}
			}
			a[i][j]=1;   //完成之后恢复原来的值,继续检测
		}
	}
}
int main(){
	cin>>n;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			cin>>a[i][j];    //输入矩阵
		}
	}
	huanghou(0,2);   //2代表黑棋,3代表白棋 
	cout<<sum; 
}