#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <queue>
using namespace std;
const int ROW = 9;
const int COL = 8;
const int KNIGHT = 10 + 1; //其实上限
const int STATE = (1 << 8); //状态上限
int cases, m, cur[ROW];
long long dp[2][KNIGHT][STATE][STATE], ans, cu, ne;
int results[STATE]; //储存每个状态的骑士数目
bool exista[STATE][STATE], existb[STATE][STATE]; //相邻两行是否能共存,相间两行是否能共存.
char mt[ROW][COL]; //储存map
template <class T>
bool read(T &n)
{
T x = 0, temp = 1;
char c;
while (((c = getchar()) < '0' || c > '9') && c != EOF && c != '-');
if (c == EOF) return false;
if (c == '-') temp = -1, c = getchar();
x = c - '0';
while ((c = getchar()) >= '0' && c <= '9') x = x * 10 + c - '0';
n = temp * x;
return true;
}
bool yes(int state, int i) //是否与皇后冲突
{
if (i < 0) return false;
return !(state & cur[i]);
}
bool okone(int i, int j) //相邻两行是否冲突
{
return !((i & (j << 2)) || (i & (j >> 2)));
}
bool okanother(int i, int j) //相间两行是否冲突
{
return !((i & (j << 1)) || (i & (j >> 1)));
}
void init()
{
for (int i = 0; i < STATE; i++)
{
for (int j = 0; j < STATE; j++)
{
if (okone(i, j)) exista[i][j] = true;
else exista[i][j] = false;
}
}
for (int i = 0; i < STATE; i++)
{
for (int j = 0; j < STATE; j++)
{
if (okanother(i, j)) existb[i][j] = true;
else existb[i][j] = false;
}
}
for (int i = 0, a, temp; i < STATE; i++)
{
temp = 0;
a = i;
while (a)
{
if (a & 1) temp++;
a >>= 1;
}
results[i] = temp;
}
}
void solve()
{
memset(dp, 0, sizeof(dp));
dp[0][0][0][0] = 1;
cu = 0, ne = 1;
ans = 0;
for (int i = 0; i < ROW - 1; i++)
{
for (int j = 0; j <= m; j++)
{
for (int k = 0; k < STATE; k++)
{
if ((!yes(k, i - 1)) && i >= 2) continue;
for (int l = 0; l < STATE; l++)
{
if (!yes(l, i) && i >= 1) continue;
if (dp[cu][j][k][l] == 0) continue;
for (int o = 0; o < STATE; o++)
{
if (!yes(o, i + 1)) continue;
if (j + results[o] > m) continue;
if (i >= 2 && !exista[k][l]) continue;
if (i >= 1 && !exista[l][o]) continue;
if (i >= 2 && !existb[k][o]) continue;
dp[ne][j + results[o]][l][o] += dp[cu][j][k][l];
}
}
}
}
memset(dp[cu], 0, sizeof(dp[cu]));
swap(cu, ne);
}
for (int i = 0; i < STATE; i++)
{
for (int j = 0; j < STATE; j++)
{
ans += dp[cu][m][i][j];
}
}
printf("%I64d\n", ans);
}
void input()
{
init();
scanf("%d", &cases);
while (cases--)
{
scanf("%d\n", &m);
memset(cur, 0, sizeof(cur));
for (int i = 1; i < ROW; i++)
{
scanf("%s", mt[i]);
for (int j = 0; j < COL; j++) //记录皇后位置
{
if (mt[i][j] == '*') cur[i] += (1 << (COL - j - 1));
}
}
solve();
}
}
int main()
{
input();
return 0;
}
g++提交
hdu4529郑厂长系列故事——N骑士问题
最新推荐文章于 2020-03-25 14:52:56 发布