CF1396B Stoned Game题解
题意
现在有\(n\)堆石子,每堆石子有\(a_i\)个,每次先手或者后手可以选择一堆石子并且从中拿出一个石子,如果这一轮操作的这个人选了这堆石子,那么下个操作的人就不能选这堆石子,最后谁不能拿石子谁输,问先手是否必胜.
分析
先来考虑一种先手必胜的情况:我们设这\(n\)堆石子的总数为\(S\),那么如果有一堆石子的个数大于\(\frac{S}{2}\),那么先手可以每次都从这堆石子中拿一个,一定会到一个状态就是只有先手拿的这一堆石子还有剩余,其他堆的石子都没有剩余,这时候先手一定胜利.
然后考虑其他情况,如果没有一堆石子的个数大于\(\frac{S}{2}\),因为如果有一堆石子的个数大于\(\frac{S}{2}\)那么先手必胜,那么这次先手拿的这个石子一定不会让这些堆中出现有一堆中剩下的石子的数量大于总石子数量的一半,同理,后手也会这样拿.那么经过一轮先后手的操作,石子总数会减少\(2\)并且会重新推回给先手.所以每经过一轮操作,石子数都会减少\(2\),最后会剩下一个或者没有石子,如果经过了若干轮,剩下了一个石子,那么先手只要拿走这个石子一定必胜,否则先手必败.
所以我们只需要记录开始的时候的石子总数\(S\),然后判断有没有一堆石子的个数大于\(S\)的一半,如果有,那么先手必胜,否则,如果\(S\)为奇数,那么先手必胜,否则先手必败.
代码
#include<bits/stdc++.h>
using namespace std;
int main(void){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
int maxs=-1;
int sum=0;
for(int i=1;i<=n;i++){
int res;
scanf("%d",&res);
if(maxs<res)
maxs=res;
sum+=res;
}
if(maxs>sum/2)
puts("T");
else if(sum%2==1)
puts("T");
else
puts("HL");
}
return 0;
}
心得
被这种题目误导了,一直在想怎么和\(SG\)函数套到一起和怎么调整,其实只要想到先手必胜的状态就简单许多了

qwq!
浙公网安备 33010602011771号