n-皇后问题的对角线与反对角线的左边映射

n皇后问题的关键就是在dfs时判断有没有皇后已经出现在该点的水平线、对角线与反对角线上,其中,水平线很好判断,难点就是将对角线和反对角线上的坐标映射,怎样才能确认两个点是否在一条对角线上呢。

我们假设两个点在一个 y = kx + b上的直线上,当k = 1则线上的点都在一条对角线上,当k = -1则线上的点都在反对角线上,我们首先枚举对角线上的点

当x = 1, y = 1 + b。

当x = 2,y = 2 + b;

当x = 3,y = 3 + b;......

此时若我们从三个数据中找出一个公式且公式的结果是相同的就可以当作我们来判断任意两个点是否在同一条对角线上的依据,不难看出y - x恒等于b,那我们就可以用一个bool数组维护x-y的值,若bool[y - x] = true;说明此对角线上已经有值,则不能放在该点,需要特殊注意的是,若b为负数会导致数组越界,此时要加上一个场数n使得结果恒大于0,即y - x + n;而 x - y + n每次值也相同,则我们只需要记忆x - y + n即可

反对角线亦是同理。y = -x + b;

当x = 1, y =  b - 1。

当x = 2,y =  b - 2;

当x = 3,y = b - 3;......

此时我们发现不管xy等于几,x + y恒等于 b,则我们记录bool[x + y]便可记录反对角线上是否已经存在一个皇后,若xy都大于0,则不会出现数组越界情况,

但为了方便记忆,我们依旧可以写成x + y + n的形式,与对角线的x - y + n形成对照

参考代码如下

 

#include <iostream>
using namespace std;

const int N = 20;
int a[N];
bool st[N], dg[N], udg[N];
int n;
void dfs(int u){
    if(u == n){
        for(int i = 0; i < n; i ++)
        {
            for(int j = 0; j < n; j ++){
                if(j == a[i]) cout << 'Q';
                else cout << '.';
            }
            cout << endl;
        }
        cout << endl;
        return;
    }
    
    for(int i = 0; i < n; i ++)
    {
        if(!st[i] && !dg[u + i + n] && !udg[i - u + n]){
            st[i] = dg[u + i + n] = udg[i - u + n] = true;
            a[u] = i;
            dfs(u + 1);
             st[i] = dg[u + i + n] = udg[i - u + n] = false;
        }
    }
}
int main()
{
    cin >> n;
    dfs(0);
    return 0;
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值