1. 程式人生 > 遊戲資訊 >《饑荒 聯機版攻略》即將登陸Switch!網易或將全資收購《底特律:成為人類攻略》開發商

《饑荒 聯機版攻略》即將登陸Switch!網易或將全資收購《底特律:成為人類攻略》開發商

✅做題思路or感想

(二刷直接初見過,在用時和記憶體消耗上遠強於一刷,我真的成長了)

經典八皇后問題,回溯法理所應當

八皇后的要求:一個皇后的上下左右,以及斜線上不能有其他皇后

故這裡的思路就是判斷當前位置是否符合八皇后的要求,符合,則回溯遞迴,不符合,則continue

遞迴三部曲

遞迴引數

  • 除了地圖和地圖大小要傳入外,這裡還需要用row來代表現在遞迴進行到的哪一行了,這裡的妙處是這樣做可以直接排除了會有皇后在同一行的可能

遞迴中止條件

  • row的值為地圖大小n時就停止遞迴,這裡注意不是row == n - 1就停了,這樣的話會不能處理最後一行!!!所以要等最後一行處理完後再停止遞迴

遞迴單層邏輯

  • 判斷當前位置是否符合條件,若符合,則去下一行接著遞迴,否則continue
class Solution {
public:
    vector<vector<string>>result;
    bool isGood(vector<string>& map, int n, int row, int col) {
        //判斷在同一列上是否有其他皇后
        //注意這裡的迴圈中止條件是i < row,而不能是i <= row,這樣的話就包括自己了!會始終return false!
        for (int i = 0; i < row; i++) {
            if (map[i][col] == 'Q')return false;
        }
        //判斷在左斜線方向上是否有其他皇后
        //注意這裡是從當前皇后的位置開始向左斜線方向遍歷,而不是從左斜線方向到當前皇后遍歷,因為不知道斜上方會在哪裡結束!!!
        //這裡的處理就算得上是八皇后問題的難點了!!!
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if (map[i][j] == 'Q')return false;
        }
        //判斷在右斜線方向刪是否有其他皇后
        //同理如上,注意這裡和上面的區別!!!!
        for (int i = row - 1, j = col + 1; i >= 0 && j >= 0; i--, j++) {
            if (map[i][j] == 'Q')return false;
        }
        return true;
    }
    void dfs(vector<string>& map, int n, int row) {
        //注意不是 row == n - 1
        if (row == n) {
            result.push_back(map);
            return;
        }
        for (int col = 0; col < n; col++) {
            if (isGood(map, n, row, col)) {
                map[row][col] = 'Q';
                dfs(map, n, row + 1);
                map[row][col] = '.';	//回溯
            }
        }
    }
    vector<vector<string>> solveNQueens(int n) {
        string str;
        //這裡是把地圖初始化為全是點,這樣子做比string(n, '.')速度更快一點
        for (int i = 0; i < n; i++) {
            str = str + ".";
        }
        vector<string> map(n, str);
        dfs(map, n, 0);
        return result;
    }
};