时间限制: 1.00s | 内存限制: 128MB
题目描述
会下国际象棋的人都很清楚: 皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8 个皇后放在棋盘(有8×8个方格) 上, 使它们谁也不能被吃掉,这 就是著名的八皇后问题。 .
对于某个满足要求的八个皇后的摆放方法 ,定 义一个皇后串 a 与之对应, 即a=b1b2…b8, 其中 bi 为相应摆法中第 i 行皇后所处的列数。已经知道八皇后问题一共有92 组解(即 92 个不同的皇后串)。
给出一个数b , 要求输出第b 个串。串的比较是这样的: 皇后串 x 置于皇后串 y 之前, 当且仅当将 x 视为整数时比 y 小。
输入
第 1 行是测试数据的组数n , 后面跟着n 行输入。每组测试数据占 1 行, 包含一个正整数b(1≤b≤92)
输出
输出有 n 行, 每行输出对应一个输入。输出应是一个正整数, 是对应于b 的皇后串。
输入输出样例
样例输入 #1
复制
2
1
92
样例输出 #1
复制
15863724
84136275
注意事项:
这里说一下为什么在if的判断里面主对角线是dig[i+row] 副对角线是udig[row-i+M]
主对角线的的直线方程为y=-x+b 那么b=x+y所以取i+row 而副对角线是 y=x+b
b=y-x 可是数组的下标不能为负数,因此加上一个M使下标为正数
代码实现:
#include<bits/stdc++.h>
using namespace std;
int n,s;
const int N = 10,M = 8;
bool col[N],dig[N*2],udig[N*2]; //检查每一列是否有皇后,主对角线和副对角线
vector<int> strs;
void dfs(int row)
{
if(row==M)
{
strs.push_back(s);
}
for (int i = 0; i < M; i ++ ) //枚举row 这一行的每一列
{
if(!col[i] && !dig[i+row] && !udig[row-i+M] )
{
col[i]=dig[i+row]=udig[row-i+M]=true;
s=s*10+(i+1);
dfs(row+1);
s/=10;// 恢复原状
col[i]=dig[i+row]=udig[row-i+M]=false;
}
}
}
int main()
{
cin>>n;
dfs(0);
sort(strs.begin(),strs.end());//需要按序输出,因此要先排序
while (n -- )
{
int b;
cin>>b; //vector内部下标从0开始
cout<<strs[b-1]<<endl;
}
return 0;
}
代码参考:
作者:Zzay
链接:https://www.acwing.com/solution/content/120004/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。