[刷题] 51 N-Queens

要求

  • 将n个皇后摆放在n*n的棋盘中,使横、竖和两个对角线方向均不会同时出现两个皇后

思路

  • 尝试在一行中摆放,如果摆不下,回到上一行重新摆放,直到所有行都摆下
  • 快速判断不合法情况
    • 竖向:col[i]表示第i列被占用
    • 对角线1(右上--左下):共2*n-1条,dia1[i]表示第i对角线1被占用
    • 对角线2(左上--右下):共2*n-1条,元素索引为i-j+n-1,dia2[i]表示第i对角线2被占用

     

          

实现

  • row:记录摆放结果,row[i]=k 表示第 i 行第 k 列有皇后
  • generateBoard():将结果转换为棋盘格形式输出
  • 27-30:回溯,比如4皇后问题,将第一行皇后摆在第一列后,尝试将第二行皇后摆在第三列(与第一行并不冲突),但发现第三行皇后无法摆放,于是返回,尝试将第二行皇后摆在第四列
  • 也就是说子问题只有完成最后一步尝试才能确定是否有解,例如你在转正前一天被发现偷公司的东西,试用期没过,人力需要把你的档案删除掉
 1 #include <vector>
 2 #include <iostream>
 3 #include <assert.h>
 4 using namespace std;
 5 
 6 class Solution {
 7     
 8 private:
 9     vector<vector<string>> res;
10     vector<bool> col, dia1, dia2;
11     
12     // 尝试在一个n皇后问题中,摆放第index行的皇后位置 
13     void putQueen(int n ,int index, vector<int> &row){
14         if( index == n){
15             res.push_back( generateBoard(n,row) );
16             return;                
17         }
18         
19         for( int i = 0 ; i < n ; i ++ )
20             // 尝试将第index行的皇后摆放在第i列 
21             if( !col[i] && !dia1[index+i] && !dia2[index-i+n-1]){
22                 row.push_back(i);
23                 col[i] = true; 
24                 dia1[index+i] = true;
25                 dia2[index-i+n-1] = true;
26                 putQueen(n, index+1, row);
27                 col[i] = false; 
28                 dia1[index+i] = false;
29                 dia2[index-i+n-1] = false;
30                 row.pop_back();
31             }
32         return;
33     }    
34     
35     vector<string> generateBoard( int n, vector<int> &row){
36         assert( row.size() == n );
37         vector<string> board(n, string(n,'.'));
38         for( int i = 0 ; i < n ; i ++ )
39             board[i][row[i]] = 'Q';
40         return board;
41     }
42     
43 public:
44     vector<vector<string>> solveNQueens(int n) {
45         
46         res.clear();
47         
48         col = vector<bool>(n,false);
49         dia1 = vector<bool>(2*n-1, false);
50         dia2 = vector<bool>(2*n-1, false);
51         
52         vector<int> row;
53         putQueen(n,0,row);
54         
55         return res;
56     }
57 };
58 
59 int main(){
60     
61     int n = 4;
62     vector<vector<string>> res = Solution().solveNQueens(n);
63     for( int i = 0 ; i < res.size() ; i ++ ){
64         for( int j = 0 ; j < n ; j ++ )
65             cout << res[i][j] << endl;
66         cout << endl;
67     }
68     return 0;
69 }
View Code

相关

  • 52 N-Queens II
  • 37 Sudoku Solver
原文地址:https://www.cnblogs.com/cxc1357/p/12711334.html