题意:如图
红色的是曹操的位置,只能有一个,然后剩下的随意摆放,输入n,看n * 4的格子内能有多少排放方式。
题解:从第一个位置检测能否摆放这几个格子,黄色要在最后,因为只占用一个位置,填充用的。。然后位置标记为1,开始递归,参数是当前有多少个位置已被摆放,能摆放对应格子且标记是0,就继续摆放,如果最后组成的格子是n*4且有一个曹操(红色格子),结果加一,每次递归结束后要把标记还原为0。
#include <stdio.h>
#include <string.h>
const int N = 4;
int n, ans, g[N][N], vis[N][N], cao;
void init() {
memset(g, 0, sizeof(g));
memset(vis, 0, sizeof(vis));
ans = cao = 0;
}
void solve(int k) {
if (k == n * 4 && cao) {
ans++;
return;
}
if (k >= n * 4)
return;
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < 4; j++) {
if (!cao && i < n - 1 && j < 3 && !vis[i][j] && !vis[i + 1][j] && !vis[i][j + 1] && !vis[i + 1][j + 1]) {
vis[i][j] = vis[i + 1][j] = vis[i][j + 1] = vis[i + 1][j + 1] = 1;
cao = 1;
solve(k + 4);
cao = 0;
vis[i][j] = vis[i + 1][j + 1] = vis[i + 1][j] = vis[i][j + 1] = 0;
}
if (i < n - 1 && !vis[i][j] && !vis[i + 1][j]) {
vis[i][j] = vis[i + 1][j] = 2;
solve(k + 2);
vis[i][j] = vis[i + 1][j] = 0;
}
if (j < 3 && !vis[i][j] && !vis[i][j + 1]) {
vis[i][j] = vis[i][j + 1] = 3;
solve(k + 2);
vis[i][j] = vis[i][j + 1] = 0;
}
if (!vis[i][j]) {
vis[i][j] = 4;
solve(k + 1);
vis[i][j] = 0;
return;//否则会死循环
}
}
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
init();
scanf("%d", &n);
if (n == 1) {
printf("0\n");
continue;
}
if (n == 2) {
printf("18\n");
continue;
}
solve(0);
printf("%d\n", ans);
}
return 0;
}