东华OJ 基础题130 2n皇后问题——难度易

文章讲述了在一个n×n的棋盘上放置n个黑皇后和n个白皇后,保证它们不在同一行、列或对角线上的问题,使用C++中的回溯算法进行求解,并提供了相关代码示例。
摘要由CSDN通过智能技术生成

问题描述 :

给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。

问总共有多少种放法?

n小于等于8。

说明:同一条对角线是指包括两条主对角线的所有对角线,n=5时的棋盘从左上往右下有9条对角线,从右上往左下也有9条对角线。

比如,棋盘为:

1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

表示一个4*4的棋盘,所有位置都可放皇后。

则可知有2种放法。

输入说明 :

输入的第一行为一个整数n,表示棋盘的大小。
接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

输出说明 :

输出一个整数,表示总共有多少种放法。

输入范例 :

4
1 0 1 1
1 1 1 1
1 1 1 1
1 1 1 1

输出范例 :

0

完整C++代码

本来想两个颜色用一个函数的,现在这样重复太多了,主要是回溯的时候,那三个数组有点难搞,如果有懂的,评论区留下代码或者私聊,谢谢🥰

#include <bits/stdc++.h>

using namespace std;

int n, res = 0;
int graph[8][8];
// 默认一开始都可以放置,w白色,b黑色 
int col_w[10] = {0}, l_up_w[10] = {0}, l_down_w[10] = {0}, col_b[10] = {0}, l_up_b[10] = {0}, l_down_b[10] = {0};

// 白色是2,黑色是3 
void dfs(int num, int color) {
	if (num == n) { 
		if (color == 3) res++;
		else dfs(0, 3);
		return;
	}
	for (int j = 0; j < n; j++) {
		// 只有1才可以放置 
		if (graph[num][j] != 1) continue;
		// 第j列、(num,j)主对角和副对角线为1才能放置,否则跳过 
		if (color == 2) {
			// 白色棋子
			if (!(col_w[j] || l_up_w[j - num + n] || l_down_w[j + num])) {
				// 可以放置 
				graph[num][j] = color;
				col_w[j] = 1;
				l_down_w[j + num] = 1;
				l_up_w[j - num + n] = 1;
				// 放置棋子
				dfs(num + 1, color);
				// 回溯
				graph[num][j] = 1; 
				col_w[j] = 0;
				l_down_w[j + num] = 0;
				l_up_w[j - num + n] = 0;
			}
		} else {
			// 黑色棋子
			if (!(col_b[j] || l_up_b[j - num + n] || l_down_b[j + num])) {
				// 可以放置 
				graph[num][j] = color;
				col_b[j] = 1;
				l_down_b[j + num] = 1;
				l_up_b[j - num + n] = 1;
				// 放置棋子
				dfs(num + 1, color);
				// 回溯
				graph[num][j] = 1; 
				col_b[j] = 0;
				l_down_b[j + num] = 0;
				l_up_b[j - num + n] = 0;
			}
		}
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> graph[i][j];
		}
	}
	dfs(0, 2);
	cout << res << endl; 
	return 0;
}

😋欢迎大伙私信或者评论区交流讨论😋

  • 14
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值