有关全排列(Permutation)的思路和代码参见前一篇文章:
http://blog.youkuaiyun.com/bcj296050240/article/details/51107056
这里叙述一下N皇后问题的解决思路:
规则:
N皇后在一个N*N的棋盘上,使其不能相互攻击,即任意两个皇后不得处于同一行,同一列或一条对角线上。
解决方法:
由于N个皇后的任意两个不能处在同一行,那么肯定是每个皇后占据一行,于是我们定义一个数组,长度为N。数组的第i个数字代表位于第i行的皇后的列号。先把数组中的N个数字用(0——N-1)初始化,然后对该数组中的数字作全排列。
因为我们是用不同的数字初始化数组,故而所有皇后肯定不同列。因此我们只需要判断每一个排列对应的N个皇后是否在同一条对角线上,也就是对于数组的两个下标i和j,是不是有 abs(A[i]-A[j]) = abs(i - j)。如果成立,则该解法不满足条件。筛选过后可以得到所有满足条件的解法。
具体代码如下:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
vector<vector<string>> solveNQueens(int n) {
vector<vector<string>> sol;
vector<vector<int>> res;
vector<int> arr;
int end = n-1;
int start = 0;
for(int i = 0;i < n;++i)
arr.push_back(i);
Permutation(res, arr, start, end);
convertSol(res, sol);
return sol;
}
void convertSol(vector<vector<int>> &res, vector<vector<string>> &sol){
for(int i = 0;i < res.size();++i){
vector<string> vec;
for(int j = 0;j < res[i].size();++j){
int pos = res[i][j];
int k = 0;
string str;
while(k < pos){
str += ".";
++k;
}
str += "Q";
++k;
while(k < res[i].size()){
str += '.';
++k;
}
vec.push_back(str);
}
sol.push_back(vec);
}
}
void Permutation(vector<vector<int>> &res, vector<int> &arr, int start, int end){
if(start == end){
bool flag = true;
for(int i = 0;i < end;++i){
for(int j = 0;j <= end;++j){
if(i != j && (abs(arr[i] - arr[j]) == abs(i-j))){
flag = false;
break;
}//if
}//for
if(!flag)
break;
}//for
if(flag)
res.push_back(arr);
}
for(int i = start;i <= end;i++){
swap(arr[i], arr[start]);
Permutation(res, arr, start+1, end);
swap(arr[i], arr[start]);
}
}
};
int main(){
Solution sul;
int n = 6;
vector<vector<string>> res = sul.solveNQueens(n);
for(int i = 0;i < res.size();++i){
cout<<"------------"<<endl;
for(int j = 0;j < res[i].size();++j)
cout<<res[i][j]<<endl;
cout<<endl;
}
getchar();
return 0;
}