[程序员面试题精选100题]58.八皇后问题
2015-04-04 22:14
543 查看
题目
在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。
思路
这就是有名的八皇后问题。解决这个问题通常需要用递归,而递归对编程能力的要求比较高。因此有不少面试官青睐这个题目,用来考察应聘者的分析复杂问题的能力以及编程的能力。
由于八个皇后的任意两个不能处在同一行,那么这肯定是每一个皇后占据一行。于是我们可以定义一个数组colIndex[8],colIndex[i]表示位于第i行的皇后的列号。先把colIndex的八个数字分别用0-7初始化,接下来我们要做的事情就是对数组colIndex做全排列。由于我们是用不同的数字初始化数组中的数字,因此任意两个皇后肯定不同列。我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是i-j==colIndex[i]-colIndex[j]或者j-i==colIndex[i]-colIndex[j]。
关于全排列问题参考:[LeetCode]46.Permutations
代码
在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。
思路
这就是有名的八皇后问题。解决这个问题通常需要用递归,而递归对编程能力的要求比较高。因此有不少面试官青睐这个题目,用来考察应聘者的分析复杂问题的能力以及编程的能力。
由于八个皇后的任意两个不能处在同一行,那么这肯定是每一个皇后占据一行。于是我们可以定义一个数组colIndex[8],colIndex[i]表示位于第i行的皇后的列号。先把colIndex的八个数字分别用0-7初始化,接下来我们要做的事情就是对数组colIndex做全排列。由于我们是用不同的数字初始化数组中的数字,因此任意两个皇后肯定不同列。我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是i-j==colIndex[i]-colIndex[j]或者j-i==colIndex[i]-colIndex[j]。
关于全排列问题参考:[LeetCode]46.Permutations
代码
/*------------------------------------ * 日期:2015-04-04 * 作者:SJF0115 * 题目: 58.八皇后问题 * 来源:程序员面试题精选100题 ---------------------------------------*/ #include <iostream> #include <vector> using namespace std; // 判断皇后是否在同一对角线上 bool Check(vector<int> colIndex,int n){ bool a,b; for(int i = 0;i < n;++i){ for(int j = i+1;j < n;++j){ a = (i - j == colIndex[i] - colIndex[j]); b = (j - i == colIndex[i] - colIndex[j]); if(a || b){ return false; }//if }//for }//for return true; } // 全排列 void Permutation(vector<int> &colIndex,int n,int index,int &count,vector<bool> &visited){ if(index == n){ // 判断皇后是否在同一对角线上 if(Check(colIndex,n)){ ++count; for(int i = 0;i < n;++i){ cout<<colIndex[i]<<" "; }//for cout<<endl; }//if return; }//if for(int i = 0;i < n;++i){ // 判断是否访问过 if(!visited[i]){ colIndex[index] = i; visited[i] = true; Permutation(colIndex,n,index+1,count,visited); visited[i] = false; }//if }//for } int EightQueen(){ int count = 0; int n = 8; // colIndex[i]表示位于第i行的皇后列号 vector<int> colIndex(n,0); vector<bool> visited(n,false); Permutation(colIndex,n,0,count,visited); return count; } int main(){ //freopen("C:\\Users\\Administrator\\Desktop\\c++.txt", "r", stdin); cout<<EightQueen()<<endl; return 0; }
相关文章推荐
- 程序员面试题精选100题(23)-跳台阶问题
- 程序员面试题精选100题(23)-跳台阶问题
- 程序员面试题精选100题(27)-二元树的深度
- 程序员面试题精选100题(34)-找出数组中两个只出现一次的数字
- 程序员面试题精选100题(12)-从上往下遍历二元树
- 程序员面试题精选100题(19)-反转链表
- 程序员面试题精选100题(18)-用两个栈实现队列
- 程序员面试题精选100题(28)-字符串的排列
- 程序员面试题精选100题(24)-栈的push、pop序列
- 程序员面试题精选100题(09)-查找链表中倒数第k个结点
- 程序员面试题精选100题(06)-判断整数序列是不是二元查找树的后序遍历结果
- 程序员面试题精选100题(21)-左旋转字符串
- 程序员面试题精选100题(32)-不能被继承的类
- 面试题精选(70):100人民币问题
- 程序员面试题精选100题(10)-在排序数组中查找和为给定值的两个数字
- 程序员面试题精选100题(01)-把二元查找树转变成排序的双向链表
- 程序员面试题精选100题(33)-在O(1)时间删除链表结点
- 程序员面试题精选(32):金币概率问题(威盛笔试题)
- 程序员面试题精选100题(18)-用两个栈实现队列
- 程序员面试题精选100题(15)-含有指针成员的类的拷贝