发现不好找策略,但是状态较少,于是可以考虑暴力喵~
可以用 位二进制编码所有的状态喵~
对于每一种合法的操作,可以枚举这个操作的补集,来建出图喵~
全填满是必败态,其它点只要有后续是必败态,就是必胜态,否则就是必败态喵~这个一轮记忆化搜索就可以全部预处理喵~
我们只需要预处理一次,就可以直接查询所有的提问喵~
爱你们喵~
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> graph(1 << 16);
int dp[1 << 16];
void AddAllEdge(int mask) {
// cout << mask << ',';
int inv = ((1 << 16) - 1) ^ mask;
int i = 0;
do {
graph[i].push_back(i | mask);
i = (i - inv) & inv;
} while (i);
}
bool Dp(int x) {
if (dp[x] != -1) {
return dp[x];
}
dp[x] = 0;
for (const auto& y : graph[x]) {
if (!Dp(y)) {
dp[x] = 1;
return true;
}
}
return false;
}
void Init() {
memset(dp, -1, sizeof(dp));
dp[(1 << 16) - 1] = 0;
for (int i = 0; i < 16; i++) {
AddAllEdge(1 << i);
}
for (int len = 2; len < 4; len++) {
//horizontal
int base = (1 << len) - 1;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5 - len; j++) {
AddAllEdge(base << (i * 4) << j);
}
}
//vertical
base = ((1 << (len * 4)) - 1) / ((1 << 4) - 1);
for (int i = 0; i < 5 - len; i++) {
for (int j = 0; j < 4; j++) {
AddAllEdge(base << (i * 4) << j);
}
}
//pie
base = ((1 << (len * 3)) - 1) / ((1 << 3) - 1);
for (int i = 0; i < 5 - len; i++) {
for (int j = len - 1; j < 4; j++) {
AddAllEdge(base << (i * 4) << j);
}
}
//na
base = ((1 << (len * 5)) - 1) / ((1 << 5) - 1);
for (int i = 0; i < 5 - len; i++) {
for (int j = 0; j < 5 - len; j++) {
AddAllEdge(base << (i * 4) << j);
}
}
}
for (int i = 0; i < 1 << 16; i++) {
Dp(i);
}
}
void Solve() {
int cur = 0;
for (int sum = 0; sum < 7; sum++) {
for (int x = max(0, sum - 3), y = sum - x; x < 4 && y > -1; x++, y--) {
char c;
cin >> c;
if (c == '*') {
cur |= 1 << (x * 4 + y);
}
}
}
cout << (dp[cur] ? "Alice\n" : "Bob\n");
}
int main() {
Init();
int T;
cin >> T;
while (T--) {
Solve();
}
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号