【题解】N皇后
题目描述
相信大家都听过经典的“八皇后”问题吧?这个游戏要求在一个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皇后的更多相关文章
- [题解]N 皇后问题总结
N 皇后问题(queen.cpp) [题目描述] 在 N*N 的棋盘上放置 N 个皇后(n<=10)而彼此不受攻击(即在棋盘的任一行,任一列和任一对角线上不能放置 2 个皇后) ,编程求解所有的 ...
- 我对DFS的理解
我对DFS的理解 [何为DFS] 深度优先搜索(Depth-First-Search),简称DFS.是一种常见搜索算法.其方法是从原点不断一条路扩散,当无路可走时回退来走下一条路,直至找到目标或遍历. ...
- 八皇后O(1)算法题解
题目描述 在国际象棋棋盘上(8*8)放置八个皇后,使得任意两个皇后之间不能在同一行,同一列,也不能位于同于对角线上.问共有多少种不同的方法,并且按字典序从小到大指出各种不同的放法. 题解 见证奇迹的时 ...
- HDU 2553 N皇后问题(详细题解)
这是一道深搜题目!问题的关键是在剪枝. 下面我们对问题进行分析: 1.一行只能放一个皇后,所以我们一旦确定此处可以放皇后,那么该行就只能放一个皇后,下面的就不要再搜了. 2.每一列只能放一个皇后,所以 ...
- PAT甲题题解-1128. N Queens Puzzle (20)-做了一个假的n皇后问题
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789810.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- 洛谷 P1219 八皇后题解
题目描述 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行.每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子. 上面的布局可以用序列2 4 6 1 3 ...
- 题解 洛谷P1562 【还是N皇后】
原题:洛谷P1562 这个题的原理和8皇后的原理是一模一样的,就是必须要用n个皇后把每一个行填满,同时满足每一列,每一行,每一条对角线只有一个棋子.但如果按照原来的方法暴打的话只有60分(优化亲测无效 ...
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同 ...
- 回溯算法之n皇后问题
今天在看深度优先算法的时候,联想到DFS本质不就是一个递归回溯算法问题,只不过它是应用在图论上的.OK,写下这篇博文也是为了回顾一下回溯算法设计吧. 学习回溯算法问题,最为经典的问题我想应该就是八皇后 ...
随机推荐
- C语言程序设计II—第八周教学
第八周教学总结(15/4-21/4) 教学内容 本周的教学内容为: 8.4 电码加密 知识点:指针与字符串,重难点:字符指针与字符串的关联和区别: 8.5 任意个整数求和 知识点:动态内存分配的概念和 ...
- 安装Debian后做的一些事情
1.source.list # aliyun deb http://mirrors.aliyun.com/debian/ stretch main non-free contrib deb http: ...
- LOJ558 我们的 CPU 遭到攻击 LCT
传送门 题意:写一个数据结构,支持森林上:连边.删边.翻转点的颜色(黑白).查询以某一点为根的某棵树上所有黑色点到根的距离和.$\text{点数} \leq 10^5 , \text{操作数} \le ...
- Codechef TAPAIR Counting the important pairs 随机化、树上差分
传送门 题意:给出一个$N$个点.$M$条边的无向连通图,求有多少组无序数对$(i,j)$满足:割掉第$i$条边与第$j$条边之后,图变为不连通.$N \leq 10^5 , M \leq 3 \ti ...
- React-UI组件和容器组件
UI组件负责页面的渲染,又叫傻瓜组件. 容器组件负责逻辑,又叫聪明组件. 当一个组件只有render函数的时候,就可以用无状态组件的形式来定义这个组件.无状态组件怎么定义呢?其实就是一个函数,接受pr ...
- 在线图标制作,格式转换 ICON
在线图标制作,格式转换 https://www.easyicon.net/covert/
- [Spark][Hive]Hive的命令行客户端启动:
[Spark][Hive]Hive的命令行客户端启动: [training@localhost Desktop]$ chkconfig | grep hive hive-metastore 0:off ...
- 如何设置本机电脑的固定IP地址?
最近使用Loadrunner需要用到IP欺骗,但是我打开设置IP欺骗却提示我:IP向导不支持启用DHCP的网卡.您的卡启用了DHCP或者配置了无效设置.请与系统管理员联系. 我就方了,于是百度了一下, ...
- Linux磁盘空间被占用问题 (分区目录占用空间比实际空间要大: 资源文件删除后, 空间没有真正释放)
问题说明:IDC里的一台服务器的/分区使用率爆满了!已达到100%!经查看发现有个文件过大(80G),于是在跟有关同事确认后rm -f果断删除该文件.但是发现删除该文件后,/分区的磁盘空间压根没有释放 ...
- PLSQL使用技巧 如何设置默认显示My Objects、记住密码等
https://www.cnblogs.com/yilinzi/p/7144852.html PL/SQL Developer实现双击table查询 https://blog.csdn.net/zhy ...