蓝桥云客--黑白皇后
1.黑白皇后【省模拟赛】 - 蓝桥云课
问题描述
给定一个 n×n 的棋盘。现在要向棋盘中放入 n 个黑皇后和 n 个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?
输入格式
输入的第一行包含一个整数 n。
输出格式
输出一行包含一个整数,表示答案。
样例输入
4
样例输出
2
评测用例规模与约定
共有 10 个评测用例,评测用例各不相同。
对于所有评测用例,2≤n≤11。
思路:
本质上个跟八皇后一样,主要是组合问题。
代码如下:
#include <bits/stdc++.h>
using namespace std;
// 白皇后
bool white_ranks[30], white_nd[30], white_pd[30];
int white_ans[20000][30];
// 黑皇后
bool black_ranks[30], black_nd[30], black_pd[30];
int black_ans[20000][30];
// 临时数组
int res[30];
// 白皇后方案数量
int w_cnt = 0;
// 黑皇后方案数量
int b_cnt = 0;
int n;
void white_dfs(int x)
{
if (x > n)
{
w_cnt++;
for (int y = 1; y <= n; y++)
{
white_ans[w_cnt][y] = res[y];
}
return;
}
for (int y = 1; y <= n; y++)
{
if (white_ranks[y] || white_nd[x + y] || white_pd[x - y + n])
{
continue;
}
white_ranks[y] = true;
white_nd[x + y] = true;
white_pd[x - y + n] = true;
res[x] = y;
white_dfs(x + 1);
res[x] = 0;
white_ranks[y] = false;
white_nd[x + y] = false;
white_pd[x - y + n] = false;
}
}
void black_dfs(int x)
{
if (x > n)
{
b_cnt++;
for (int y = 1; y <= n; y++)
{
black_ans[b_cnt][y] = res[y];
}
return;
}
for (int y = 1; y <= n; y++)
{
if (black_ranks[y] || black_nd[x + y] || black_pd[x - y + n])
{
continue;
}
black_ranks[y] = true;
black_nd[x + y] = true;
black_pd[x - y + n] = true;
res[x] = y;
black_dfs(x + 1);
res[x] = 0;
black_ranks[y] = false;
black_nd[x + y] = false;
black_pd[x - y + n] = false;
}
}
int main()
{
cin >> n;
// 搜索白皇后的放置方案
white_dfs(1);
// 搜索黑皇后的放置方案
black_dfs(1);
int total = 0;
for (int i = 1; i <= w_cnt; i++)
{
for (int j = 1; j <= b_cnt; j++)
{
bool found = true;
for (int k = 1; k <= n; k++)
{
if (white_ans[i][k] == black_ans[j][k])
{
found = false;
break;
}
}
if (found)
{
total++;
}
}
}
cout << total;
return 0;
}