《饑荒 聯機版攻略》即將登陸Switch!網易或將全資收購《底特律:成為人類攻略》開發商
阿新 • • 發佈:2022-04-01
✅做題思路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; } };