不懂
S
G
SG
SG 函数的可以看我的博客 数学篇 ,这题给定一个无限大的二维平面,但是限制了左上角的位置,棋子的可行方向如图所示。
同样也是两人轮流移动多个棋子,无合法操作时输掉游戏,问你先手胜还是后手胜。
这题因为他的子状态到当前状态的递推关系不是线性的,所以需要用 D F S DFS DFS 记忆化搜索,来存贮结果。
代码如下:
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long LL;
const int maxn = 1e3 + 5;
int SG[maxn][maxn], vis[maxn];
bool visSG[maxn][maxn];
vector<pair<int, int>> f;
inline void init(){
f.push_back(make_pair(1, -2));
f.push_back(make_pair(-1, -3));
f.push_back(make_pair(-1, -2));
f.push_back(make_pair(-2, -1));
f.push_back(make_pair(-3, -1));
f.push_back(make_pair(-2, 1));
}
inline int dfs(int x, int y){
if(visSG[x][y]) return SG[x][y];
else visSG[x][y] = true;
int nowid = x*500 + y;
for(int i = 0, sonx, sony; i < f.size(); i++){
sonx = x + f[i].first;
sony = y + f[i].second;
if(sonx >= 0 && sony >= 0)
dfs(sonx, sony);
}
for(int i = 0, sonx, sony; i < f.size(); i++){
sonx = x + f[i].first;
sony = y + f[i].second;
if(sonx >= 0 && sony >= 0)
vis[SG[sonx][sony]] = nowid;
}
for(int i = 0; i < maxn; i++)
if(vis[i] != nowid){
SG[x][y] = i;
break;
}
return SG[x][y];
}
int main(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
init();
int t, n, x, y, ans;
visSG[0][0] = true;
cin >> t;
for(int i = 1; i <= t; i++){
cin >> n;
ans = 0;
while(n--){
cin >> x >> y;
ans ^= dfs(x, y);
}
cout << "Case " << i << ": ";
if(ans) cout << "Alice" << endl;
else cout << "Bob" << endl;
}
}