思路
记 $S = \sum_{i = 1}^{n} a_i$。
必胜态:$\exists a_i, s.t. a_i > \lfloor \frac{S}{2} \rfloor$。原因:先手只取满足条件的那堆,当后手把其它堆都取完,先手那堆仍然还有石子,因此后手败。
必败态:$\forall a_i, s.t. a_i \le \lfloor \frac{S}{2} \rfloor \wedge 2 \mid S$。证明:
归纳法
- $S = 0$ 时,满足以上条件,且先手必败。
- 假设 $S \in [2, k]$ 时,若以上条件成立,则先手必败。当 $S = k + 2$ 时,若以上条件成立,则至少还剩两堆石子,否则 $a_1 = S > \lfloor \frac{S}{2} \rfloor$。那么,先手从任意堆拿走一颗石子后,如果局面变成必胜态,则先手必败。否则,$\forall a_i, s.t. a_i \le \lfloor \frac{k + 1}{2} \rfloor = \lfloor \frac{k}{2} \rfloor$。此时,后手随意从另外一堆拿走一颗石子后,满足 $\forall a_i, s.t. a_i \le \lfloor \frac{k}{2} \rfloor \wedge 2 \mid k$,根据假设先手必败。
由此得证。
构造法
从左往右,从上到下为每颗石子编号,即第一堆石子从上到下依次编号为 $1 \sim a_1$,第二堆石子从上到下依次编号为 $a_1 + 1 \sim a_1 + a_2$,以此类推。则 $\forall i \in [1, \frac{S}{2}]$,总能找到 $i + \frac{S}{2} \in [\frac{S}{2} + 1, S]$。并且 $i$ 与 $i + \frac{S}{2}$ 不可能在同一堆,否则这一堆石子个数就会大于等于 $i + \frac{S}{2} - i + 1 > \frac{S}{2}$。因此当先手取 $i$ 时,后手可以取 $i + \frac{S}{2}$。反之,若先手取 $i + \frac{S}{2}$,则后手可以取 $i$。如此操作,最后一颗石子一定会被后手拿到。
若 $\forall a_i, s.t. a_i \le \lfloor \frac{S}{2} \rfloor \wedge 2 \not \mid S$,设 $S = 2k + 1, k \in N$,则 $\forall a_i, s.t. a_i \le \lfloor \frac{2k + 1}{2} \rfloor = \lfloor \frac{2k}{2} \rfloor$。此时先手从任意堆取走一颗石子后,局面变成 $\forall a_i, s.t. a_i \le \lfloor \frac{2k}{2} \rfloor \wedge 2 \mid 2k$,即必败态,因此先手必胜。
总结:当且仅当 $\exists a_i, s.t. a_i > \lfloor \frac{S}{2} \rfloor$ 或 $\forall a_i, s.t. a_i \le \lfloor \frac{S}{2} \rfloor \wedge 2 \not \mid S$ 时,先手必胜。
时间复杂度 $O(n)$。
#include <iostream>
using namespace std;
void solve() {
int n;
cin >> n;
int sum = 0, mx = 0;
for (int i = 0, x; i < n; i++) {
cin >> x;
sum += x;
mx = max(mx, x);
}
if (mx > sum / 2 || sum & 1)
cout << "T" << endl;
else
cout << "HL" << endl;
}
int main() {
cin.tie(0)->sync_with_stdio(0);
int t;
cin >> t;
while (t--) solve();
return 0;
}