题目:

八皇后问题:在8 X 8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处于同一行,同一列或者同意对角线上,求出所有符合条件的摆法。

思路:

1、回溯法

数据结构:

由于8个皇后不能处在同一行,那么肯定每个皇后占据一行,这样可以定义一个数组A[8],数组中第i个数字,即A[i]表示位于第i行的皇后的列号。

满足条件:任意两个皇后不同列,即A[i]!=A[j],任意两个皇后不在同一对角线上,即abs(i-j)!=abs(A[i]-A[j])。

算法:

回溯法,通过深度遍历的形式枚举数组A的所有排列组合,并通过剪枝的形式(判断是否满足上述的条件)来减少不必要的计算量,详见代码。

2、全排列法

思路与字符串排列一样http://www.cnblogs.com/AndyJee/p/4655485.html,只是还需要对每一种排列做判断。

数据结构:

8个皇后不能处在同一行,那么肯定每个皇后占据一行,这样可以定义一个数组A[8],数组中第i个数字,即A[i]表示位于第i行的皇后的列号,先把数组A[8]分别用0-7初始化。

满足条件:由于我们用0-7这7个不同的数字初始化数组,因此任意两个皇后肯定也不同列,那么我们只需要判断每个排列对应的8个皇后中是否有任意两个在同一对角线上即可,即对于数组的两个下标i和j,如果i-j==A[i]-A[j]或i-j==A[j]-A[i],则认为有两个元素位于了同一个对角线上,则该排列不符合条件。

思路:

参考字符串排列:

求整个字符串的排列,可以分成两步:首先求所有可能出现在第一个位置的字符,即把第一个字符和后面的所有字符交换;然后固定第一个字符,求后面所有字符的排序。此时仍把后面的字符看成两部分,第一个字符和后面的字符,然后重复上述步骤。(递归)

然后判断每一种排列是否满足上述添加即可。

代码:

1、回溯法

#include <iostream>
#include <vector>
#include <stdlib.h> using namespace std;
int count=0; bool canPlace(int index,const vector<int> &result){
for(int i=0;i<index;i++){
if(result[index]==result[i] || abs(index-i)==abs(result[index]-result[i]))
return false;
}
return true;
} void queen(int index,vector<int> &result,int N){
if(index==N){
for(int i=0;i<N;i++)
cout<<result[i]<<" ";
cout<<endl;
count++;
return;
}
for(int i=0;i<N;i++){
result[index]=i;
if(canPlace(index,result))
queen(index+1,result,N);
}
} int main()
{
int n=8;
vector<int> result; for(int i=0;i<n;i++)
result.push_back(i);
queen(0,result,n);
cout<<count<<endl;
return 0;
}

2、全排列法

#include <iostream>
#include <vector>
#include <stdlib.h> using namespace std;
int count=0; void swap(int *a,int *b){
int tmp=*a;
*a=*b;
*b=tmp;
} void queen_permutation(vector<int> &result,int index,int len){
bool can=true;
if(index==len-1){
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
if(i-j==result[i]-result[j] || i-j==result[j]-result[i]){
can=false;
break;
}
}
if(can==false)
break;
}
if(can){
for(int i=0;i<len;i++)
cout<<result[i];
cout<<endl;
count++;
}
}
else{
for(int i=index;i<len;i++){
swap(result[index],result[i]);
queen_permutation(result,index+1,len);
swap(result[index],result[i]);
}
}
} int main()
{
int n=8;
vector<int> result; for(int i=0;i<n;i++)
result.push_back(i);
queen_permutation(result,0,n);
cout<<count<<endl;
return 0;
}

(算法)N皇后问题的更多相关文章

  1. 回溯算法————n皇后、素数串

    回溯就是算法是搜索算法中一种控制策略,是一个逐个试探的过程.在试探的过程中,如果遇到错误的选择,就会回到上一步继续选择下一种走法,一步一步的进行直到找到解或者证明无解为止. 如下是一个经典回溯问题n皇 ...

  2. 算法——八皇后问题(eight queen puzzle)之回溯法求解

    八皇后谜题是经典的一个问题,其解法一共有种! 其定义: 首先定义一个8*8的棋盘 我们有八个皇后在手里,目的是把八个都放在棋盘中 位于皇后的水平和垂直方向的棋格不能有其他皇后 位于皇后的斜对角线上的棋 ...

  3. [算法] N 皇后

    N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行.同一列.同一斜线上的皇后都会自动攻击). 一. 求解N皇后问题是算法中回溯法应用的一个经典案例 回溯算 ...

  4. JS算法之八皇后问题(回溯法)

    八皇后这个经典的算法网上有很多种思路,我学习了之后自己实现了一下,现在大概说说我的思路给大家参考一下,也算记录一下,以免以后自己忘了要重新想一遍. 八皇后问题 八皇后问题,是一个古老而著名的问题,是回 ...

  5. 回溯算法 - n 皇后问题

    (1)问题描述 在 n × n 格的棋盘上放置彼此不受攻击的 n 个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n 后问题等价于在 n × n 的棋盘上放置 n 个 ...

  6. 7, java数据结构和算法: 八皇后问题分析和实现 , 递归回溯

    什么是八皇后问题: 指的是,在一个8 * 8的棋盘中, 放置8个棋子, 保证这8个棋子相互之间, 不在同一行,同一列,同一斜线, 共有多少种摆法? 游戏连接: http://www.4399.com/ ...

  7. noj算法 8皇后打印 回溯法

    描述: 输出8皇后问题所有结果. 输入: 没有输入. 输出: 每个结果第一行是No n:的形式,n表示输出的是第几个结果:下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格.不同的结果中,先输出第 ...

  8. 算法——n皇后问题

    n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案. 每一种解法包含一个明确的 n 皇后问题的棋 ...

  9. 洛谷 P1219 八皇后【经典DFS,温习搜索】

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

  10. 【学习总结】java数据结构和算法-第一章-内容介绍和授课方式

    总目录链接 [学习总结]尚硅谷2019java数据结构和算法 github:javaDSA 目录 几个经典算法面试题 算法和数据结构的重要性 几个经典算法面试题 字符串匹配 暴力法:慢 kmp算法:更 ...

随机推荐

  1. .htaccess 文件的使用

    用于服务器对文件夹的控制 官方解释为 :分布式配置文件 ,提供了针对目录改变配置的方法; 项目可以有多个这样的配置文件,子目录文件会覆盖父目录的配置 在apache(这里泛指服务器)中,/conf/v ...

  2. JBPM4入门——5.流程定义的发布、查询、删除

    本博文只是简要对JBPM4进行介绍,如需更详细内容请自行google 链接: JBPM入门系列文章: JBPM4入门——1.jbpm简要介绍 JBPM4入门——2.在eclipse中安装绘制jbpm流 ...

  3. 看来ms sql server if 中定义个变量出了if 还是可以用的

    begin declare @abc int; end print @abc 可以打出1出来

  4. Linux makefile教程之函数七[转]

    使用函数 ———— 在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能.make所支持的函数也不算很多,不过已经足够我们的操作了.函数调用后,函数的返回值可以当做 ...

  5. base64 encoding

    //https://en.wikipedia.org/wiki/Base64 std::string base64Encode(const std::vector<char>& b ...

  6. PHP实现的Mysql读写分离

    本代码是从uchome的代码修改的,是因为要解决uchome的效率而处理的.这个思维其实很久就有了,只是一直没有去做,相信也有人有同样的想法,如果有类似的,那真的希望提出相关的建议.封装的方式比较简单 ...

  7. cocos2dx 内存管理的理解

    关于引擎内存管理的细节,网上有大量的详解,这里概括一下: cocos2d-x 的世界是基于 CCObject 类构建的,所以内存管理的本质就是管理一个个 CCObject. //CCObject 内部 ...

  8. Java 断点调试总结

    为了准备调试,你需要在代码中设置一个断点先,以便让调试器暂停执行允许你调试,否则,程序会从头执行到尾,你就没有机会调试了. 1. 条件断点 断点大家都比较熟悉,在Eclipse Java 编辑区的行头 ...

  9. 用Python组合Celery Redis RabbitMQ进行分布式数据抓取

    首先,记录下遇到的问题吧,在抓取的过程中为了避免IO操作,主要用Redis做插入缓存,当内存占用率很大时,会周期性的持续到Mysql里 虽然是拆东墙补西墙,但把数据抓取完毕后持续化可以慢慢进行,毕竟数 ...

  10. STL源码剖析读书笔记--第四章--序列式容器

    1.什么是序列式容器?什么是关联式容器? 书上给出的解释是,序列式容器中的元素是可序的(可理解为可以按序索引,不管这个索引是像数组一样的随机索引,还是像链表一样的顺序索引),但是元素值在索引顺序的方向 ...