蓝桥杯 2n皇后问题

题目描述

在这里插入图片描述


样例输入:

在这里插入图片描述


在这里插入图片描述

思路

本题考查的是深度优先搜索+回溯。对比N皇后的问题,此题需要在N皇后的基础上再放一个皇后,且条件也要符合皇后在棋盘上的规则,所以我们可以先深搜去放黑皇后,每放一个黑皇后给当前棋盘对应的位置标志为 22代表黑皇后),所以 dfs 就需要一个标志代表当前是深搜放黑皇后还是白皇后,我们用flag来表示。2 表示黑皇后,3 表示白皇后。N皇后的基本解法是,我们暴力枚举,我们可以试一试第一行的第一个位置、第二个位置…以此类推。当这一行放好我们就dfs去下一行搜索,直到行越界且皇后都放完那么这次就是有效的,2n皇后在此基础上需要添加标志位当一个皇后放完之后,我们需要继续dfs0行开始放下一个皇后,再次到行越界且两个皇后的数量都已经为0(放完),我们统计次数。

代码

#include <iostream>
#include <vector>
using namespace std;

// 2n皇后问题

int n = 0;
vector< vector<int> >grid;
int black = 0;
int white = 0;

/*
	0:代表不能放皇后
	1:代表可以放皇后
	2:代表黑皇后
	3:代表白皇后
*/
int res = 0;

bool isLegal(int row, int col, int flag);	// 声明

void dfs(int row , int flag) { // flag代表现在深搜是放黑皇后还是白皇后
	if (row == n) {
		if (black == 0 && white) {
			dfs(0 , 3);
		}
		else if (black == 0 && white == 0) {
			res++;
			// 找到结果打印一下棋盘
			/*cout << endl << endl;
			for (auto& v : grid) {
				for (auto val : v) {
					cout << val << " ";
				}
				cout << endl;
			}*/
		}
		return;
	}


	for (int i = 0; i < n; i++) { // 当前行的每一个位置都遍历一下
		if (grid[row][i] == 1 && isLegal(row, i , flag)) {
			grid[row][i] = flag;
			if (flag == 2) black--;
			else white--;
			dfs(row + 1 , flag);	// 深度优先搜索
			// 回溯
			grid[row][i] = 1; 
			if (flag == 2) black++;
			else white++;
		}
	}
}

// flag 2 || 3
bool isLegal(int row , int col , int flag) {
	// 行无需检查因为深度优先搜索的时候已经可以确定行不会重复
	for (int i = 0; i < n; i++) {
		if (grid[i][col] == flag) return false;
	}
	for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
		if (grid[i][j] == flag) return false;
	}
	for (int i = row, j = col; i < n && j < n; i++, j++) {
		if (grid[i][j] == flag) return false;
	}
	for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
		if (grid[i][j] == flag) return false;
	}
	for (int i = row + 1, j = col - 1; i < n && j >= 0; i++, j--) {
		if (grid[i][j] == flag) return false;
	}
	return true;
}

int main() {

	cin >> ::n;
	black = white = n;
	grid = vector< vector<int> >(n , vector<int>(n));
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			cin >> grid[i][j];
	dfs(0 , 2);	// 先放黑皇后
	cout << ::res << endl;

	return 0;
}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值