题目链接: Stoned Game
大致题意
有 n n n堆石子, 第 i i i堆有 a i a_i ai个.
A和B轮流取石子, A先取.
每次可以选择一个非空石子堆, 并从中拿走
1
1
1个石子.
限制: 当前玩家选择的石子堆不能和上一个玩家相同.
谁最终不能取石子了, 谁就输了.
问: 谁会获得胜利.
解题思路
博弈
首先考虑去除限制, 我们很容易得出结论: 当石子总数是奇数, 先手胜, 反之后手胜.
思路一:
我们现在加上限制, 考虑到一种特殊局势, 有一堆石子很多, 比其他所有堆加和还要多. 那么先手只需要一直选择这堆石子, 必胜.
否则, 任何人都不希望对方拿到这种特殊局势. 考虑到每次每个人都只能使得一堆石子减少1, 因此特殊局势不会在游戏过程中出现. 故答案同去除限制的情况.
解释: 为什么初始不是特殊局势, 后续也不会出现特殊局势?
每个人肯定都希望自己拿到特殊局势, 但最初的特殊局势的转化一定是: 最大堆有 x x x个, 此时其余堆总和也有 x x x个, 然后由对方从其他堆中拿走1个 形成的.
显然对方并不会给出特殊局势. 因此对方一定会拿最大堆的石子. 那么下一种特殊局势是: 最大堆有 x − 1 x - 1 x−1个, 其他堆也有 x − 1 x - 1 x−1个, 然后由对方从其他堆拿走1个 形成.
你会发现这个过程会反复进行, 一直持续到所有堆的石子都被拿完.
思路二:
我们考虑加上限制后, 什么情况下会受到限制的约束:
其实就是当两个人都要去拿同一堆石子的时候. 那什么情况下, 两个人需要去拿同一堆石子? 当且仅当只剩一堆石子时. 否则另外一个人可以拿其他堆石子, 来保证自己不输.
因此两个人都希望自己面对 仅剩一堆石子的的情况, 但这种情况我们同样发现需要对方给出, 但对方又不傻, 一定不会主动给出这个局面.
但是我们发现, 如果初始局面是 思路一 中的特殊局势, 那么先手只需要一直拿最大堆, 后手迫不得已会给出仅剩一堆石子的局面. 此时后手就败了. 反之, 答案同于没有约束的情况.
综上所述, 我们只需要判断初始局面是否为特殊局势.
若是, 则先手胜. 否则, 当石子总数是奇数时, 先手胜. 反之, 后手胜.
AC代码
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
int main()
{
int t; cin >> t;
while (t--) {
int n; cin >> n;
int all = 0, fmax = 0;
rep(i, n) {
int x; scanf("%d", &x);
all += x; fmax = max(fmax, x);
}
if (fmax > all - fmax) puts("T");
else {
puts(all & 1 ? "T" : "HL");
}
}
return 0;
}