题意:n皇后问题,输入一行字符串,长度是n就是n*n的棋盘,如果字符是‘?’就是这一列任意位置都可以摆放皇后,如果i是1~F,是这一列第i行必须摆放一个皇后。
题解:f[i][j]数组是在第i行第j列摆放皇后的总方法数,状态转移方程f[i][j] += f[i - 1][k] (|j - k| > 1)。最后把最后一列的方法数加起来就是总的方法数。
#include <stdio.h>
#include <string.h>
#include <math.h>
const int N = 20;
char str[N];
long long f[N][N];
int n;
int main() {
while (scanf("%s", str) != EOF) {
memset(f, 0, sizeof(f));
n = strlen(str);
if (str[0] == '?')
for (int i = 0; i < n; i++)
f[i][0] = 1;
else if (str[0] >= 'A' && str[0] <= 'F')
f[str[0] - 'A' + 9][0] = 1;
else if (str[0] >= '1' && str[0] <= '9')
f[str[0] - '1'][0] = 1;
for (int i = 1; i < n; i++) {
if (str[i] == '?') {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
if (fabs(j - k) <= 1)
continue;
f[j][i] += f[k][i - 1];
}
}
}
else {
if (str[i] >= 'A' && str[i] <= 'F') {
int j = str[i] - 'A' + 9;
for (int k = 0; k < n; k++) {
if (fabs(j - k) <= 1)
continue;
f[j][i] += f[k][i - 1];
}
}
else if (str[i] >= '1' && str[i] <= '9') {
int j = str[i] - '1';
for (int k = 0; k < n; k++) {
if (fabs(j - k) <= 1)
continue;
f[j][i] += f[k][i - 1];
}
}
}
}
long long res = 0;
for (int i = 0; i < n; i++)
res += f[i][n - 1];
printf("%lld\n", res);
}
return 0;
}