题目描述

  相信大家都听过经典的“八皇后”问题吧?这个游戏要求在一个8×8的棋盘上放置8个皇后,使8个皇后互相不攻击(攻击的含义是有两个皇后在同一行或同一列或同一对角线上)。

  桐桐对这个游戏很感兴趣,也很快解决了这个问题。可是,他想为自己增加一点难度,于是他想求出n皇后的解的情况。

  你能帮助她吗?

输入输出格式

输入格式

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

输出格式

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

输入输出样例

输入样例

8

输出样例

92

题解

  经典dfs题。在搜索的时候枚举位置显然会超时,我们可以用三个数组分别记录当前列和当前两条对角线是否有被使用。具体细节如下。

#include<iostream>

using namespace std;

int n;
int ans;
int a[],b[],c[]; void Queen(int x)
{
if(x>n)
{
ans++;
return;
} for(int y=;y<=n;y++)
if(!a[y]&&!b[x-y+n]&&!c[x+y-])
{
a[y]=b[x-y+n]=c[x+y-]=;
Queen(x+);
a[y]=b[x-y+n]=c[x+y-]=;
}
} int main()
{
cin>>n;
Queen();
cout<<ans; return ;
}

参考程序

  但是极限数据还是可以把这个程序卡掉。我们可以思考,其实棋盘的摆放是满足对称性的,第一行我们只需要搜索一半就行了,这样就将时间复杂度缩小一半,刚好可以卡过。

#include<iostream>

using namespace std;

int n;
int ans;
int a[],b[],c[]; void Queen(int x)
{
if(x>n)
{
ans++;
return;
} if(x==)
{
for(int y=;y<=n/;y++)
if(!a[y]&&!b[x-y+n]&&!c[x+y-])
{
a[y]=b[x-y+n]=c[x+y-]=;
Queen(x+);
a[y]=b[x-y+n]=c[x+y-]=;
}
}
else
{
for(int y=;y<=n;y++)
if(!a[y]&&!b[x-y+n]&&!c[x+y-])
{
a[y]=b[x-y+n]=c[x+y-]=;
Queen(x+);
a[y]=b[x-y+n]=c[x+y-]=;
}
}
} void Queen2(int x)
{
if(x>n)
{
ans++;
return;
} if(x==)
for(int y=n/+;y<=n/+;y++)
if(!a[y]&&!b[x-y+n]&&!c[x+y-])
{
a[y]=b[x-y+n]=c[x+y-]=;
Queen(x+);
a[y]=b[x-y+n]=c[x+y-]=;
}
else
for(int y=;y<=n;y++)
if(!a[y]&&!b[x-y+n]&&!c[x+y-])
{
a[y]=b[x-y+n]=c[x+y-]=;
Queen(x+);
a[y]=b[x-y+n]=c[x+y-]=;
}
} int main()
{
cin>>n;
Queen();
ans*=;
if(n%==) Queen2(); cout<<ans; return ;
}

参考程序

  观察搜索过程,我们在枚举可放位置上花费了很多时间,其实我们可以直接用三个二进制数来表示当前行的可放位置,用lowbit来提取就行了。

#include <iostream>

using namespace std;

int n;
int lim;
int ans; void DFS(int a, int b, int c)
{
if(a == lim)
{
++ans;
return;
}
int tmp = lim & ~(a | b | c) , pos;
while(tmp)
{
pos = tmp & -tmp;
tmp -= pos;
DFS(a + pos, b + pos >> , c + pos << );
}
return;
} int main()
{
cin >> n;
lim = ( << n) - ;
int mid = << (n >> );
for(register int i = ; i < mid; i <<= )
{
DFS(i, i >> , i << );
}
ans <<= ;
if(n & ) DFS( << (n >> ), << (n >> ) - , << (n >> ) + );
// DFS(0, 0, 0);
cout << ans;
return ;
}

参考程序(位运算优化)

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

  1. [题解]N 皇后问题总结

    N 皇后问题(queen.cpp) [题目描述] 在 N*N 的棋盘上放置 N 个皇后(n<=10)而彼此不受攻击(即在棋盘的任一行,任一列和任一对角线上不能放置 2 个皇后) ,编程求解所有的 ...

  2. 我对DFS的理解

    我对DFS的理解 [何为DFS] 深度优先搜索(Depth-First-Search),简称DFS.是一种常见搜索算法.其方法是从原点不断一条路扩散,当无路可走时回退来走下一条路,直至找到目标或遍历. ...

  3. 八皇后O(1)算法题解

    题目描述 在国际象棋棋盘上(8*8)放置八个皇后,使得任意两个皇后之间不能在同一行,同一列,也不能位于同于对角线上.问共有多少种不同的方法,并且按字典序从小到大指出各种不同的放法. 题解 见证奇迹的时 ...

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

    这是一道深搜题目!问题的关键是在剪枝. 下面我们对问题进行分析: 1.一行只能放一个皇后,所以我们一旦确定此处可以放皇后,那么该行就只能放一个皇后,下面的就不要再搜了. 2.每一列只能放一个皇后,所以 ...

  5. PAT甲题题解-1128. N Queens Puzzle (20)-做了一个假的n皇后问题

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789810.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  6. 洛谷 P1219 八皇后题解

    题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 ...

  7. 题解 洛谷P1562 【还是N皇后】

    原题:洛谷P1562 这个题的原理和8皇后的原理是一模一样的,就是必须要用n个皇后把每一个行填满,同时满足每一列,每一行,每一条对角线只有一个棋子.但如果按照原来的方法暴打的话只有60分(优化亲测无效 ...

  8. 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同 ...

  9. 回溯算法之n皇后问题

    今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...

随机推荐

  1. 【Codeforces 1120C】Compress String

    Codeforces 1120 C 题意:给一个串\(S\),将这个串分成\(t_1..t_m\),如果\(t_i\)在\(t_1..t_{i-1}\)中作为子串出现过,那么这个的代价是\(b\),否 ...

  2. docker核心概念(镜像、容器、仓库)及基本操作

    概要 docker是一种linux容器技术.容器有效的将由单个操作系统挂管理的资源划分到孤立的组中,以便更好的在组之间平衡有冲突的资源使用需求.可简单理解为一种沙盒 .每个容器内运行一个应用,不同的容 ...

  3. leetcode56:Merge Intervals

    大都是自定义了 Interval的比较方法. 突发奇想 int [] arr=new int[intervals.Count*2]; for(int i=0;i<intervals.Count; ...

  4. 开发工具|给你的项目买份保险:Python虚拟环境

    读完需要 9 分钟 1. 什么是虚拟环境? 虚拟环境的意义,就如同 虚拟机 一样,它可以实现不同环境中Python依赖包相互独立,互不干扰.这在一定程度的意义上,给了我们的项目一份很有力的保障.在这里 ...

  5. curl发送json格式数据

    php的curl方法详细的见官方手册. curl_setopt用法:  http://www.php.net/manual/en/function.curl-setopt.php <?php $ ...

  6. Ionic app 上传图片之webApi接口

    App上传图片对应的webApi服务端是怎么处理的呢? using System; using System.Collections.Generic; using System.Diagnostics ...

  7. 多线程-volatile关键字和ThreadLocal

    1.并发编程中的三个概念 原子性:一个或多个操作.要么全部执行完成并且执行过程不会被打断,要么不执行.最常见的例子:i++/i--操作.不是原子性操作,如果不做好同步性就容易造成线程安全问题. 可见性 ...

  8. [Oracle]Oracle Fail Safe 与 SQLNET.AUTHENTICATION_SERVICES关系

    现象: 在使用 OFS (Oracle Fail Safe)的环境中,把数据库的 SQLNET.AUTHENTICATION_SERVICES 从 NTS 改为 NONE之后,当从 Oracle Fa ...

  9. 【译】高级指南-深入JSX

    title: 高级指南-深入JSX date: 2017-4-5 17:13:09 --- 深入JSX 从根本上来讲,JSX 仅仅是提供 React.createElement(component, ...

  10. rsync同步时,删除目标目录比源目录多余文件的方法(--delete)

    在日常运维工作中,我们经常用到rsync这个同步神器.有时在同步两个目录时,会要求删除目标目录中比源目录多出的文件,这种情况下,就可用到rsync的--delete参数来实现这个需求了. 实例说明:在 ...