【CF1425A】 Arena of Greed题解

原题链接
简要翻译:
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('\n');
    }
    return 0;
}
posted @ 2020-09-28 00:10  喵乖乖喵  阅读(462)  评论(0编辑  收藏  举报

膜拜众神

网安院技术部     ZZY大师     Xinyang 大佬     Wjyyy