八皇后(N皇后)
xiufanivan · · 个人记录
- 用动态数组
#include <bits/stdc++.h>
using namespace std;
int n; // n皇后
int cnt = 0;
vector<string> queen; // 皇后位置,".":表示可放置,"Q":表示皇后位置
vector<vector<int> > attack; // 是否可放皇后,"0":表示可以放,"1":表示不能放
// 放置皇后
void put_queen(int x, int y) {
// 方向数组
int dx[]={-1, -1, -1, 0, 1, 1, 1, 0};
int dy[]={-1, 0, 1, 1, 1, 0, -1, -1};
// 修改attack二维数组
attack[x][y] = 1; // 皇后放置的位置
// 修改皇后攻击到的位置
for (int i = 1; i < n; i++) { // i:皇后攻击距离(1~n-1)
for (int j = 0; j < 8; j++) { // 遍历8个方向
// nx、ny:修改的坐标,
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;
}
}
}
}
// 回溯递归函数
// k:当前处理行,
void backtrack(int k) {
if (k == n) { // 找到一组解
cnt++;
cout << "解法" << cnt << ":" << endl;
for (int i = 0; i < queen.size(); i++) {
cout << queen[i] << endl;
}
return;
}
// 遍历0~n-1列,试探皇后可放置位置
for (int i = 0; i < n; i++) {
if (attack[k][i] == 0) {
vector<vector<int> > temp = attack; // 备份attack数组
queen[k][i] = 'Q'; // 修改queen数组
put_queen(k, i); // 更新attack数组
backtrack(k + 1); // 递归试探k+1行
attack = temp; // 恢复attack数组
queen[k][i] = '.'; // 恢复queen数组
}
}
}
int main() {
cin >> n;
// 初始化queen和attack二维数组
for (int i = 0; i < n; i++) {
attack.push_back(vector<int>());
string s;
for (int j = 0; j < n; j++) {
attack[i].push_back(0);
s += ".";
}
queen.push_back(s);
}
// 递归搜索
backtrack(0);
return 0;
}
- 用普通二维数组
#include <bits/stdc++.h>
using namespace std;
int n; // n皇后
int cnt = 0; // 记录解法个数
char queen[10][10]; // 皇后位置,".":表示可放置,"Q":表示皇后位置
int attack[10][10]; // 是否可放皇后,"0":表示可以放,"1":表示不能放
// 放置皇后
void put_queen(int x, int y, int n) {
// 方向数组
int dx[]={-1, -1, -1, 0, 1, 1, 1, 0};
int dy[]={-1, 0, 1, 1, 1, 0, -1, -1};
// 修改attack二维数组
attack[x][y] = 1; // 皇后放置的位置
// 修改皇后攻击到的位置
for (int i = 1; i < n; i++) { // i:皇后攻击距离(1~n-1)
for (int j = 0; j < 8; j++) { // 遍历8个方向
// nx、ny:修改的坐标,
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;
}
}
}
}
// 备份数组(a拷贝给b)
void copy(int a[10][10], int b[10][10], int n) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
b[i][j] = a[i][j];
}
}
}
// 回溯递归函数
// k:当前处理行,
void backtrack(int k, int n) {
if (k == n) { // 找到一组解
cnt++;
cout << "解法" << cnt << ":" << endl;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << queen[i][j];
}
cout << endl;
}
return;
}
// 遍历0~n-1列,试探皇后可放置位置
for (int i = 0; i < n; i++) {
if (attack[k][i] == 0) {
int tem[10][10]; // 备份数组
copy(attack, tem, n); // 备份attack数组
queen[k][i] = 'Q'; // 修改queen数组
put_queen(k, i, n); // 更新attack数组
backtrack(k + 1, n); // 递归试探k+1行
copy(tem, attack, n); // 恢复attack数组
queen[k][i] = '.'; // 恢复queen数组
}
}
}
int main() {
cin >> n;
// 初始化queen和attack二维数组
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
queen[i][j] = '.';
attack[i][j] = 0;
}
}
// 递归搜索
backtrack(0, n);
return 0;
}