题目描述
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2…b8,其中bi为相应摆法中第i行皇后所处的列数。已经知道8皇后问题一共有92组解(即92个不同的皇后串)。 给出一个数b,要求输出第b个串。串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小。
输入描述:
每组测试数据占1行,包括一个正整数b(1 <= b <= 92)
输出描述:
输出有n行,每行输出对应一个输入。输出应是一个正整数,是对应于b的皇后串。
示例1
输入
2
1
92
输出
15863724
84136275
解题思路
这道题可以用DFS解决。最主要的就是需要求出所有92种可能序列,储存起来,对应输出就行。DFS每次搜索一行。(DFS可用于判断是否有解,有多少不同的解,BFS用于求最优解)
1、首先可以用一个position数组(下标表示行,数值表示列),例如position[1]=1,代表第一个皇后放在第一行第一列。为了让结果更加方便描述,我们下标从1开始。
2、每次求出一个坐标,便与前面的进行比较,判断新坐标是否合理。合理则遍历下一行,不合理则position[i]换下一个值。
代码描述
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
vector<int> vec; //用来放最终的结果
int position[9]; //行号从1开始,其中下标代表行号,其中存放的内容代表列号
void DFS(int row) //row代表要放入的行号,逐行放入,因为要用的是列号,而且按照习惯都是一列一列计算的
{
if (row == 9) //row==9意味着从1~8行全都放入,已完成解
{
int temp = 0;
for (int i = 1; i <= 8; i++) //把数组的内容转成十进制
{
temp*=10;
temp+=position[i];
}
vec.push_back(temp); //把得到的结果放进vector
}
else
{
for (int i = 1; i <= 8; i++)
{
position[row] = i; //i在这里代表列号
bool flag = true; //用一个标志位来标记,是否冲突
for (int j = 1; j < row; j++) //判断这个数和之前的数是否有冲突
{
if (position[row] == position[j] ||
row - position[row] == j - position[j] ||
row + position[row] == j + position[j])
//列不相等,主对角线不相等,副对角线不相等 行必然不相等,不用比较
{
flag = false;
break;
}
}
if (flag) //全部合理 则遍历下一行
DFS(row + 1);
}
}
}
int main()
{
DFS(1); //直接从第一行开始放
int n;
while (scanf("%d", &n) != EOF)
{
printf("%d\n", vec[n - 1]); //因为vector是从0开始的
}
return 0;
}
参考代码:https://www.nowcoder.com/questionTerminal/fbf428ecb0574236a2a0295e1fa854cb?f=discussion