• 【题解】N皇后问题


    题目描述

    相信大家都听过经典的“八皇后”问题吧?这个游戏要求在一个8×8的棋盘上放置8个皇后,使8个皇后互相不攻击(攻击的含义是有两个皇后在同一行或同一列或同一对角线上)。
    桐桐对这个游戏很感兴趣,也很快解决了这个问题。可是,他想为自己增加一点难度,于是他想求出n皇后的解的情况。
    你能帮助她吗?

    输入输出格式

    输入格式:

    一行,仅有一个数n(1≤n≤14),表示为n皇后问题。

    输出格式:

    输出仅有一个数,表示n皇后时问题的解法总数。

    输入输出样例

    输入样例:

    8

    输出样例:

    92
    这道题用搜索可以压线过,所以就讲一讲搜索的做法
    首先我们想到用二维数组做,但是二维数组肯定会超时,所以我们用降维做法,原先在棋盘上(1,1)位置有棋子,就把数组chessboard[1][1]标记为1
    然后我们可以吧它改为(1,1)有棋子就把chessboard[1]标记为1,这样可以减少时间复杂度,13皇后可以压线过
    然后我们再优化,用数组计数,我们发现,第i行的棋子会在第(x+i)条正对角线上,会在第(x-i+n)条反对角线上,就用数组计数,每访问一次这个对角线,就把它标记为1,即可减少超时
    可是这个做法对于14皇后还需要大约两秒,我们再优化
    发现这个棋盘具有对称性,以4皇后为例,举例如下
    0 1 0 0
    0 0 0 1
    1 0 0 0
    0 0 1 0
    如果这个做法可行,那么下列做法
    0 0 1 0
    1 0 0 0
    0 0 0 1
    0 1 0 0
    也是可行的,所以第一行只需要放到((n+1)/2)就可以了
    至此,基本可以吧14皇后优化至1秒内
    具体程序如下:

    #include<cstdio>
    using namespace std;
    int queen[15],n,ans;
    int tr1[35],tr2[35],tr3[35];
    void dfs(int x)
    {
        if(x>n)
        {
            ans+=2;
            return;
        }
        for(register int i=1;i<=n;++i)
        {
            if(tr1[i]==0&&tr2[x+i]==0&&tr3[x-i+n]==0)
            {
                queen[x]=i;
                tr1[i]=1;
                tr2[x+i]=1;
                tr3[x-i+n]=1;
                dfs(x+1);
                tr1[i]=0;
                tr2[x+i]=0;
                tr3[x-i+n]=0;
                queen[x]=0;
            }
        }
    }
    void newdfs(int x)
    {
        if(x>n)
        {
            ans+=2;
            return;
        }
        for(register int i=1;i<=n/2;++i)
        {
            if(tr1[i]==0&&tr2[x+i]==0&&tr3[x-i+n]==0)
            {
                queen[x]=i;
                tr1[i]=1;
                tr2[x+i]=1;
                tr3[x-i+n]=1;
                dfs(x+1);
                tr1[i]=0;
                tr2[x+i]=0;
                tr3[x-i+n]=0;
                queen[x]=0;
            }
        }
    }
    int main()
    {
        scanf("%d",&n);
        if(n==1)
        {
            cout<<1;
            return 0;
        }
        for(register int i=1;i<=n/2;++i)
        {
            queen[1]=i;
            tr1[i]=1;
            tr2[i+1]=1;
            tr3[1-i+n]=1;
            dfs(2);
            tr1[i]=0;
            tr2[i+1]=0;
            tr3[1-i+n]=0;
        }
        if(n%2==1)
        {
            queen[1]=(n/2+1);
            tr1[(n/2+1)]=1;
            tr2[(n/2+1)+1]=1;
            tr3[1-(n/2+1)+n]=1;
            newdfs(2);
        }
        printf("%d",ans);
    }
    

    参考文献:N皇后的多种巧妙解法

  • 相关阅读:
    Key Figure、Exception Aggreagion、Non-Cumulative KeyFigure
    特征创建:Reference Characteristic、Template
    Compounding绑定属性
    特征的SID表、M表、P表、Q表、X表、Y表、T表
    特征的Attribute Only选项
    将InfoObject作为信息提供者Characteristic is InfoProvider
    滚动RollUp、压缩
    Aggregation 聚集
    VirtualProvider (VirtualCube)虚拟立方体
    自建数据源(RSO2)、及数据源增强
  • 原文地址:https://www.cnblogs.com/2021-yanghaoran/p/10837844.html
Copyright © 2020-2023  润新知