题目来源:Codeforces Round #666 (Div. 2) - D
题意:
已知n堆石子a和每堆石子的个数,两个人轮流取石子,每次可以从任意一堆石子中取走一个,但不能从另一个人上次取的堆中取,第一个人第一次可以任意取,最终无法取的人输。判断游戏的胜利者。
思路:
首先,当有一堆的石子足够多时,先手可以一直从该堆中取,直到后手把其他的堆取完时该堆仍有剩余,此时先手必胜。设第p堆的石子数最多,sum为总石子数,而满足该情况的条件即为a[p]>sum-a[p](必胜态)。
其次,当上述情况不满足时,即初始时a[p]<=sum-a[p]。假设两个人先都取第p堆以外的堆,那么如果到某个人要取的时候,此时a[p]=sum-a[p],那么等他取完以后另一个人为必胜态,所以他只能从第p堆取。之后另一人因为游戏规则而只能取其他堆,他还是取第p堆。最终所有石子被取完。
如果开始时两个人可以任意取(可以直接取第p堆),那么此时p(最大堆)即是动态变化的,如果取第p堆而使得其不是最大堆了,此时再取该堆时还是相当于取第p堆以外的堆,最终所有石子还是会被取完。
所以,如果初始时必胜态不满足时,所有石子一定会被取完,可根据总个数的奇偶性判断胜利者。
代码:
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
#include <deque>
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<P,int> Q;
const int inf1=1e9+9;
const ll inf2=1e16+9;
const ll mol=1e9+7;
const int maxn=1e5+9;
const ll maxx=1e12+9;
int n,ar[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d",&ar[i]);
sort(ar,ar+n);
int sum=0;
for(int i=0;i<n;i++) sum+=ar[i];
if(ar[n-1]>sum-ar[n-1]||sum&1) printf("T\n");
else printf("HL\n");
}
}