题目连接: 八皇后问题
题目:
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。
对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b 1b 2…b 8,其中b i为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。
给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
Input
第1行是测试数据的组数n,后面跟着n行输入。每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
Output
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
Sample Input
2
1
92
Sample Output
15863724
84136275
注: 字符串中的数字表示不同行上的列坐标 例如15863724的含义是八个皇后分别位于(1, 1), (2, 5), (3, 8), (4, 6), (5, 3), (6, 7), (7, 2), (8, 4)处.
解题思路:
本题是DFS算法的一道经典例题, 一共8*8的棋盘要放8个皇后, 并且他们彼此还无法相互攻击,
那么我们很容易得到一个结论: 8个皇后一定处于8个不同行上, 也处于8个不同列上.因此我们可以通过一个整型一维数组来记录不同行上皇后所处的列.
当进行搜索时, 我们不妨就让第n个皇后处于第n行上, 然后判断该列8个位置能否放置该皇后, 若可以则继续深入, 直到8个皇后都放置好时进行结果记录.
由于一共92种结果顺序是一定的, 因此我们可以进行结果预处理.
AC代码:
#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#define ll long long
using namespace std;
int location[10]; //皇后位置记录
string result[100];
int cou = 0; //结果统计
bool check(int x, int y) //检查该位置是否能放皇后
{
for (int i = 1; i < x; i++) {
if (location[i] == y) return 0; //处于同一列, 不符合条件
if (location[x - i] == y - i || location[x - i] == y + i) return 0; //处于对角, 不符合条件
}
return 1;
}
void dfs(int n) //n表示当前要放第n个皇后, 我要把他放在第n行上
{
if (n == 9) { //当函数进入达到第九层时, 说明8个皇后都已经安放好, 进行结果记录
for (int i = 1; i <= 8; i++) {
result[cou] += location[i] + '0'; //要存放成字符型, 所以要加上'0'
}
cou++;
return;
}
for (int i = 1; i <= 8; i++) { //尝试把这个皇后放在不同列上
if (check(n, i)) {
location[n] = i;
dfs(n + 1);
}
}
}
int main(void)
{
dfs(1); //跑出全部的结果
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
cout << result[n-1] << endl;
}
return 0;
}
由于本题的特殊性, 即我们明白8个皇后一定分别处于不同行列上, 所以可以略去回溯步骤, 但是在深搜中回溯是常常与其相伴的.
END
来源:CSDN
作者:逍遥Fau
链接:https://blog.csdn.net/weixin_45799835/article/details/104186302