有關全排列(Permutation)的思路和代碼參見前一篇文章:
http://blog.csdn.net/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;
}