1. 程式人生 > 實用技巧 >題解 AT47 【パズルのお手伝い】

題解 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;
}