问题描述 :
给定一个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;
}
😋欢迎大伙私信或者评论区交流讨论😋