题目
在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;
}