P10507 Georgia and Bob 题解
题目链接
题目大意
一个一行的棋盘,棋盘上有 \(n\) 个棋子,两人轮流选择一枚棋子向左移动若干格(会被其他棋子阻拦),询问谁必赢。
解题思路
显然为博弈论。注意到对于两个相邻(指棋子,不是位置)的棋子,若先手移动了左边的棋子若干格,后手也能移动右边的棋子相同的步数,所以对于相邻两对棋子中间的间隔是对结果没有影响的(先后手一人一次解决)。于是问题转化为了怎么处理一对棋子的间隔。显然,一对棋子间的间隔可以类比为石子,转化为 Nim 游戏。特别的,若棋子数为单数,则将第一枚棋子与边界 \(0\) 组成一对。
为便于读者理解,给出一个具体的游戏过程:
代码
// Problem: P10507 Georgia and Bob
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P10507
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// Date: 2025-02-07 09:49:04
//
// Powered by CP Editor (https://cpeditor.org)#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mst(x, y) memset(x, y, sizeof(x))
#define pii pair<int, int>
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
#define pb(x) push_back(x)int read(){int x = 0, f = 1;char c = getchar();while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9'){x = 10*x+c-'0';c = getchar();}return f*x;}
void writ(int x){if(x < 0){putchar('-');x = -x;}if(x > 9) writ(x/10);putchar(x%10 | 0x30);return;}
void write(int x){writ(x);puts("");}
void wr(int x){writ(x);putchar(' ');}
const int N = 1005, inf = 0x3f3f3f3f;int n, a[N], t, res;void init(){t = read();
}
void solve(){while(t--){n = read(), res = 0;for(int i = 1;i <= n;i++) a[i] = read();sort(a+1, a+1+n);if(n&1) for(int i = 1;i <= n;i += 2) res ^= (a[i]-a[i-1]-1);else for(int i = 2;i <= n;i += 2) res ^= (a[i]-a[i-1]-1);if(res) puts("Georgia will win");else puts("Bob will win");}
}signed main(){init();solve();return 0;
}