算法思想:定义一个二维数组attack,0表示可以放置皇后不会被攻击,1表示不可以放置皇后会被攻击。定义一个二维数组queen记录皇后放置的位置,Q代表放置,代表空格。 //从第0行开始尝试放置皇后,如果当前位置attack=0则放置,先备份attack,然后更新,尝试下一行皇后放置,如果尝试结束则恢复attack,恢复取消当前位置的放置,如果n行尝试结束,则记录解法。
更新八个方向的方法,记一下用两个for循环+idx[],+idy[],设置一下边界,一开始用递归写了,因为会递归会有很多重复搜索,导致超时。
#include<iostream> #include<vector> #include<string> using namespace std; void put_queen(int n,int x, int y, vector<vector<int>>& attack) { int dx[] = { -1,-1,-1,0, 1, 1, 1, 0 }; int dy[] = { -1,0, 1, 1, 1, 0,-1,-1 }; attack[x][y] = 1; for (int i = 1; i <n; i++)//从1延伸到n-1的距离 for (int j = 0; j < 8; j++) {//从八个方向延伸 int nx = x + i * dx[j]; int ny = y + i * dy[j]; if (nx >= 0 && nx < n && ny >= 0 && ny < n) { attack[nx][ny] = 1; } } } //算法思想:定义一个二维数组attack,0表示可以放置皇后不会被攻击,1表示不可以放置皇后会被攻击。定义一个二维数组queen记录皇后放置的位置,Q代表放置,代表空格。 //从第0行开始尝试放置皇后,如果当前位置attack=0则放置,先备份attack,然后更新,尝试下一行皇后放置,如果尝试结束则恢复attack,恢复取消当前位置的放置,如果n行尝试结束,则记录解法。 void backtrack(int k,int n,vector<vector<int>> &attack, vector<string>queen, vector<vector<string>>& solve) { if (k == n) { solve.push_back(queen); } else { for (int i = 0; i < n; i++) { if (attack[k][i] == 0) { vector<vector<int>>tmp = attack;//备份attack queen[k][i] = 'Q';//放置皇后 put_queen(n,k, i, attack);//更新attack backtrack(k + 1, n, attack, queen, solve);//尝试下一行 attack = tmp;//恢复attack queen[k][i] = '.';//恢复皇后位置 } } } } vector<vector<string>> solveNQueens(int n) { vector<vector<string>> solve; vector<vector<int>> attack(n, vector<int>(n, 0)); vector<string>queen; for (int i = 0; i < n; i++) { queen.push_back(""); queen[i].append(n, '.'); } backtrack(0, n, attack, queen, solve); return solve; } int main() { vector<vector<string>> solve=solveNQueens(8); for (auto it : solve) { for (int i = 0; i < it.size(); i++) { cout << it[i] << " "; } } }