原题链接
简要翻译:
Mr.Chanek与另一个人玩一个取硬币游戏,他先手。玩家在自己的回合内可以取走硬币堆中的一个。如果硬币堆里有偶数个硬币,玩家也可以选择取走硬币总数的一半。两名玩家都是绝对聪明的,他们都希望拿到手中的硬币尽可能多。
这道题的坑点在于游戏人的目的是最大化手上的硬币数量,而不是比对手多来赢得比赛。
在可以取 (n/2) 时马上取确实能保证比对手多,但是这不一定能使手上的硬币最大化。
也就是说,我们希望取走 (n/2) ,但不一定现在。
我们需要再单独取走1个逼迫对手取走下一个,使我在取走 (n/2) 后留下的还是一个奇数。
这里需要注意的是 (n=4) 时,直接取走2要更优。
目测每次n为偶数就直接取 (n/2) 的不是TLE就是WA,至于为什么会T,我也很好奇
#include <cstdio>
typedef long long ll;
#define REG register
inline char getc(){
static char buf[1<<14],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<14,stdin),p1==p2)?EOF:*p1++;
}
inline ll scan(){
REG ll a=0; REG char ch=0;
while(ch<48) ch=getc();
while(ch>=48) a=a*10+ch-48,ch=getc();
return a;
}
inline void print(ll x){
if(x>9){
print(x/10); putchar(x%10+48);
}else{
putchar(x+48);
}
}
ll t,x;
int main(){
t=scan();
while(t--){
x=scan();
REG ll c=1,d,ans=0;
while(x){
if(x&1) d=1;
else{
if((x>>1)&1) d=x>>1;
else{
if(x>4) x-=2,ans++;
d=x>>1;
}
}
if((c++)&1) ans+=d;
x-=d;
}
print(ans); putchar('
');
}
return 0;
}