题解 AT47 【パズルのお手伝い】
题意:
很经典的八皇后问题,已知三个皇后的位置,求剩下五个皇后的位置,如果无解输出“\(No Answer\)”
思路:
很显然dfs可以解决,暴力枚举每一行放的位置,通过已经放过的皇后的位置可以判断出很多不合法的位置,加上该剪枝即可
代码实现:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
inline int read () {
int x = 0, f = 1; char ch = getchar();
for (;!isdigit(ch); ch = getchar()) if (ch == '-') f = -1;
for (; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
return x * f;
}
const int maxn = 10;
int choose[maxn][maxn];
int ans[maxn][maxn];
int col[maxn];
void updata (int x, int y) {
for (int k = 1; k <= 8; k++) choose[x][k]++, choose[k][y]++;
for (int k = 1; k + x <= 8 && k + y <= 8; k++) choose[x + k][y + k]++;
for (int k = 1; x - k >= 1 && y - k >= 1; k++) choose[x - k][y - k]++;
for (int k = 1; x - k >= 1 && y + k <= 8; k++) choose[x - k][y + k]++;
for (int k = 1; x + k <= 8 && y - k >= 1; k++) choose[x + k][y - k]++;
choose[x][y]--;
}
void Delete (int x, int y) {
for (int k = 1; k <= 8; k++) choose[x][k]--, choose[k][y]--;
for (int k = 1; k + x <= 8 && k + y <= 8; k++) choose[x + k][y + k]--;
for (int k = 1; x - k >= 1 && y - k >= 1; k++) choose[x - k][y - k]--;
for (int k = 1; x - k >= 1 && y + k <= 8; k++) choose[x - k][y + k]--;
for (int k = 1; x + k <= 8 && y - k >= 1; k++) choose[x + k][y - k]--;
choose[x][y]++;
}
bool judge = false;
void dfs (int num) {
if (num == 9) {
judge = true;
return;
}
if (col[num]) dfs (num + 1);
if (judge == true) return;
for (int i = 1; i <= 8; i++) {
if (choose[num][i]) continue;
ans[num][i] = 1;
updata (num, i);
dfs (num + 1);
if (judge == true) return;
ans[num][i] = 0;
Delete (num, i);
}
if (judge == true) return;
}
int main () {
char c;
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
scanf (" %c", &c);
if (c == 'Q') {
if (choose[i][j] != 0) return puts("No Answer"), 0;
ans[i][j] = 1;
col[i] = 1;
updata (i, j);
}
}
}
dfs (1);
if (judge == true) {
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
if (ans[i][j] == 1) printf ("Q");
else printf (".");
}
puts("");
}
} else {
puts("No Answer");
}
return 0;
}