题目描述

  相信大家都听过经典的“八皇后”问题吧?这个游戏要求在一个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. AI 反向传播神经网络

    反向传播(Back Propagation,简称BP)神经网络

  2. ASP.NET Log4net 记录日志

    1.安装方式一(官网下载) 2.安装方式二(NuGet安装log4net) 3.使用步骤 4.自定义属性:UserIP UserName ActionsClick Message 概述:Log4net ...

  3. C语言程序设计II—第六周教学

    第六周教学总结(1/4-7/4) 教学内容 本周的教学内容为:第八章 指针 8.1 密码开锁(知识点:指针和指针变量的概念),8.2 角色互换(知识点:指针作为函数的参数返回多个值) 重点.难点:指针 ...

  4. [07] 使用注解完成IOC配置

    1.扫描配置 之前使用的Spring的Bean管理都是通过xml的配置文件来操作的,在Spring3.0之后已经引入了注解形式,Spring可以在指定路径下进行扫描,寻找标注了@Component.@ ...

  5. java算法----排序----(2)选择排序

    package log; public class Test4 { /** * java算法---选择排序 * * @param args */ public static void main(Str ...

  6. NIO之缓冲区

    NIO引入了三个概念: Buffer 缓冲区 Channel 通道 selector 选择器 1.java.io优化建议 操作系统与Java基于流的I/O模型有些不匹配.操作系统要移动的是大块数据(缓 ...

  7. HAProxy 日志输出及配置

    正所谓,没有软件敢说没有bug,人无完人,software is  not perfect software.是软件就可能存在bug,那么如果出现bug,我们就要分析对我们业务的影响及可能如何避免bu ...

  8. 【下一代核心技术DevOps】:(三)私有代码库阿里云Git使用

    1. 引言 使用DevOps肯定离不开和代码的集成.所以要想跑通整套流程,代码库的选型也是非常重要的.否则无法实现持续集成.目前比较常用的代码管理有SVN和GIt 如果还使用SVN的,建议尽早迁移到G ...

  9. Mvc_前后端绑定数据json集合

    ViewBag.SysModuleList =new  List<SysModule>(){.....}; var data = @Html.Raw(Json.Encode(ViewBag ...

  10. Linux下的Mongodb部署应用梳理

    一.Mongodb简介  官网地址:http://www.mongodb.org/ MongoDB是一个高性能,开源,无模式的文档型数据库,是当前NoSql数据库中比较热门的一种.MongoDB 是一 ...