1. 程式人生 > >n queens ii(n皇后問題-只計數不儲存)

n queens ii(n皇后問題-只計數不儲存)

n皇后問題2(儲存並返回所有的解決方案)

題目描述

Follow up for N-Queens problem.
Now, instead outputting board configurations, return the total number of distinct solutions.

題目大意

著名n皇后問題。
n個皇后擺放在N x N的棋盤格中,使得橫、豎和兩個對角線方向均不會同時出現兩個皇后。
只返回解決方案總數

思路

n皇后問題當n大於等於4才有討論意義,而且不只有一個解決方案;
用遞迴的方法找到每一種解決方案;
在當前解決方案中,遍歷每一行的每一列查詢可以放置皇后的位置;
在當前行中,遍歷每一列的每一個位置,假設當前位置可以放,然後進行合法性判斷,合法則放置;
然後再遞迴判斷下一行;
遞迴結束後,將當前行當前列的位置回溯,置為未放狀態,再接著判斷當前行下一列,目的是為了找到所有的解決方案。

程式碼

#include<iostream>
#include<vector>
using namespace std;
/*
    函式宣告
*/
// n皇后問題解決函式
int totalNQueens(int n);
// 遞迴實現深度優先搜尋尋找解決方案
void dfs(vector<string > &arr, int n, int row, int &sum);
// 判斷當前arr[row][col]是否可以放一個皇后
bool is_valid(vector<string > &arr, int n, int row, int col);
/*
    n:n皇后問題
*/
int totalNQueens(int n)
{
    vector<string > arr(n, string(n, '.'));
    int sum = 0;
    dfs(arr, n, 0, sum);
    return sum;
}
/*
    arr:用這個陣列儲存得到的n皇后問題的當前解決方案
    n:n皇后問題
    row:遞迴尋找當前行的皇后放在哪一列
    sum:總的解決方案數
*/
void dfs(vector<string > &arr, int n, int row, int &sum)
{
    if(row == n)
    {
        sum++; // 解決方案數加一
        /* 輸出解決方案
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                cout<<arr[i][j]<<' ';
            }
            cout<<endl;
        }
        */
        return;
    }
    for(int i=0; i<n; i++)
    {
        // 判斷是否可以在arr[row][i]放一個皇后
        if(is_valid(arr, n, row, i))
        {
            arr[row][i] = 'Q';
            dfs(arr, n, row+1, sum); // 遞迴判斷下一列
            arr[row][i] = '.'; // 回溯判斷下一列
        }
    }
}
/*
    arr:用這個陣列儲存得到的n皇后問題的當前解決方案
    n:n皇后問題
    row、col:當前判斷的是第row行、第col列
*/
bool is_valid(vector<string > &arr, int n, int row, int col)
{
    // 檢查列
    for(int i=0; i<row; i++)
    {
        if(arr[i][col] == 'Q')
        {
            return false;
        }
    }

    // 檢查對角線
    for(int i=row-1,j=col-1; i>=0&&j>=0; i--,j--)
    {
        if(arr[i][j] == 'Q')
        {
            return false;
        }
    }

    // 檢查副對角線
    for(int i=row-1,j=col+1; i>=0&&j<n; i--,j++)
    {
        if(arr[i][j] == 'Q')
        {
            return false;
        }
    }

    return true;
}

int main()
{
    cout << "請輸入皇后的個數:" << endl;
    int n;
    cin >> n;
    cout << n << "皇后問題共有 " << totalNQueens(n) << " 種解決方案。" << endl;
    return 0;
}

執行結果

以上。