【题解】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皇后的多种巧妙解法

原文地址:https://www.cnblogs.com/2021-yanghaoran/p/10837844.html

时间: 2024-11-13 09:35:46

【题解】N皇后问题的相关文章

我对DFS的理解

[何为DFS] 深度优先搜索(Depth-First-Search),简称DFS.是一种常见搜索算法.其方法是从原点不断一条路扩散,当无路可走时回退来走下一条路,直至找到目标或遍历. [框架] 1 int dfs(int n) { 2 if(到达目标)return n; 3 else{ 4 for(int i=0;i<下一步走法数;++i){ 5 int temp=dfs(n+x); 6 if(temp!=-1)return temp; 7 } 8 } 9 return -1; 10 } [我对

HDU 2553 N皇后问题(详细题解)

这是一道深搜题目!问题的关键是在剪枝. 下面我们对问题进行分析: 1.一行只能放一个皇后,所以我们一旦确定此处可以放皇后,那么该行就只能放一个皇后,下面的就不要再搜了. 2.每一列只能放一个皇后,所以我们下次搜索就不要再搜已经放过的皇后了. 3.斜的45°线也只能放一个. 综上如何才能最快速的确定一列和45°是否用过这个是个关键步骤,一旦此步骤确定我们就可以很快的进行搜索了. 我们用三个数组来保存他的每一个状态及(三个方向 ↑ ) 但是如果我们保存↑(每一列方向上的皇后)是非常容易保存的 但是保

洛谷 P1219 八皇后 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1219 题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下: 行号 1 2 3 4 5 6 列号 2 4 6 1 3 5 这只是跳

搜索入门练习题5 八皇后问题 题解

题目来源:<信息学奥赛一本通>例5.4 题目描述 要在国际象棋棋盘(\(8 \times 8\) 的棋盘)中放 \(8\) 个皇后,使任意两个皇后都不能互相吃.(提示:皇后能吃同一行.同一列.同一对角线的任意棋子.) 输出格式 输出一个整数,用于表示八皇后问题的放置方案. 题目分析 首先我们用 \((x,y)\) 来表示棋盘上第 \(x\) 行第 \(y\) 列的格子的坐标. 那么,两个皇后 \((x_1,y_1)\) 和 \((x_2,y_2)\) 会互相攻击当且仅当满足如下条件之一: 在同

[OpenJudge] 百练2754 八皇后

八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(即92个不同的皇后串).给出一个数b,要求输出第b个串.串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小. I

3101: N皇后

3101: N皇后 Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 88  Solved: 41[Submit][Status][Discuss] Description n*n的棋盘,在上面摆下n个皇后,使其两两间不能相互攻击… Input 一个数n Output 第i行表示在第i行第几列放置皇后 Sample Input 4 Sample Output 2 4 1 3 HINT 100%的数据3<n<100

常州Day4题解

1. 高精度 这题略水,字符串可过,还不加压位等,操作只有BitShift和add/sub,不过编程复杂度有些高.(输出都是二进制我能说些什么...) 2. N皇后问题 (警告! 不是平时你见到的N皇后问题...是一道Hash的模拟题,N皇后的位置都给你了,就是统计) 二级标题很详细了,搜索那些解N皇后问题的千万莫戳进来. 3. Sam数 一道比较有意思的题. 题意是,给定一个k,求所有k位数中所有相邻两位数差都小于等于2的数.输出$\mod{10^9+7}$ 说的不够明白.来个例子: $213

数据结构应用案例——栈结构用于8皇后问题的回溯求解

[说明]本文来自由周世平老师主编的<C语言程序设计>教材.我作为参编人员执笔了第7.8章."第8章 问题求解与算法"中"8.6.1 回溯法"以8皇后问题的求解为例,介绍了回溯法的解题过程.这个解决方案中用到了"栈",引用至此,作为栈应用的例子.需要说明的是,教材面向程序设计初学者,并全文中并未提出过任何关于"栈"的描述.这样做,隐藏了术语,减少初学者的认知难度.对于数据结构的学习者而言,由于知识面的扩大,却用不着回

codevs 1295 N皇后问题

时间限制: 2 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上. 输入描述 Input Description 给定棋盘的大小n (n ≤ 13) 输出描述 Output Description 输出整数表示有多少种放置方法. 样例