题目地址:
https://www.acwing.com/problem/content/description/3475/
会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将
8
8
8个皇后放在棋盘上(有
8
×
8
8×8
8×8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题。对于某个满足要求的
8
8
8皇后的摆放方法,定义一个皇后串
a
a
a与之对应,即
a
=
b
1
b
2
…
b
8
a=b_1b_2…b_8
a=b1b2…b8,其中
b
i
b_i
bi为相应摆法中第
i
i
i行皇后所处的列数。
已经知道
8
8
8皇后问题一共有
92
92
92组解(即
92
92
92个不同的皇后串)。
给出一个数
b
b
b,要求输出第
b
b
b个串。串的比较是这样的:皇后串
x
x
x置于皇后串
y
y
y之前,当且仅当将
x
x
x视为整数时比
y
y
y小。
输入格式:
第一行包含整数
n
n
n,表示共有
n
n
n组测试数据。
每组测试数据占
1
1
1行,包括一个正整数
b
b
b。
输出格式:
输出有
n
n
n行,每行输出对应一个输入。
输出应是一个正整数,是对应于
b
b
b的皇后串。
数据范围:
1
≤
b
≤
92
1≤b≤92
1≤b≤92
先用DFS暴力求解所有的解,应答询问的时候直接查表即可。代码如下:
#include <iostream>
using namespace std;
bool col[10], diag[20], udiag[20];
int idx;
string res[100];
void dfs(int u, string& s) {
if (u == 8) {
res[++idx] = s;
return;
}
for (int i = 0; i < 8; i++)
if (!col[i] && !diag[7 - i + u] && !udiag[i + u]) {
col[i] = diag[7 - i + u] = udiag[i + u] = true;
s += to_string(i + 1);
dfs(u + 1, s);
col[i] = diag[7 - i + u] = udiag[i + u] = false;
s.pop_back();
}
}
int main() {
string s;
dfs(0, s);
int T;
scanf("%d", &T);
while (T--) {
int n;
scanf("%d", &n);
cout << res[n] << endl;
}
}
预处理时间复杂度 O ( 8 8 ) O(8^8) O(88),每次询问时间 O ( 1 ) O(1) O(1),空间 O ( 1 ) O(1) O(1)。