八皇后问题 递归+回溯 (n皇后)

时间限制: 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
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 18
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值