用全排列方法解決N皇后問題(Leetcode 51)

有關全排列(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章