2020牛客寒假算法基础集训营5.E——Enjoy the game【博弈】

题目传送门


题目描述

牛牛战队的三个队员在训练之余会自己口胡了一些题当做平时的益智游戏。有一天牛可乐想出了一个小游戏给另外两名队员玩,游戏规则如下:

  • 初始一共有nn张卡牌
  • 先手第一步最少要拿1张牌,最多要拿n-1张牌。
  • 接下来每一步,双方最少要拿1张牌,最多拿等同于上一步对方拿的牌数的牌。
  • 拿走最后一张牌的人将取得游戏的胜利。

你作为旁观者,看着他们玩的很开心,想参与到这场游戏中来,赌一赌谁会能赢。


输入描述:

输入数据包含一个整数 n ( 2 n 1 0 18 ) n(2 \leq n \leq 10^{18}) ,表示初始卡牌张数。


输出描述:

如果先手有必胜策略,输出Bob,否则输出Alice。


输入

2


输出

Alice


说明

先手必须拿走一张牌,然后后手拿走了另一张牌,游戏结束。


题解

  • 首先给出正解:但凡是 2 n 2^n 都是后手赢
  • 看图,我们只考虑先手自己能否赢在这里插入图片描述
  • n = 1 n=1:胜
  • n = 2 n=2:败 ,只能是自己拿一个,对方拿一个,然后GG
  • n = 3 n=3:胜 ,自己拿一个,令对方到达 n = 2 n=2 的必败点
  • n = 4 n=4:败 ,如图红色箭头所指两种情况,都是必败状态
  • n = 5 n=5:胜 ,拿 1 1 个,令对方到达 n = 4 n=4 的必败点
  • n = 6 n=6:胜 ,拿 2 2 个,令对方到达 n = 4 n=4 的必败点
  • n = 7 n=7:胜 ,拿 3 3 个,令对方到达 n = 4 n=4 的必败点
  • n = 8 n=8:败 ,无论怎么拿,都会达到对方的必胜点。
  • 由此我们可以发现,若当前必败点为 x x ,距离下一个必败点的距离,就是 2 x 2x 位置
  • 也就是必败点为: 2 4 8 16 32 . . . 2 n 2,4,8,16,32,...,2^n

AC-Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    ll n;    while(cin >> n){
        cout << ((n&(-n)) == n ? "Alice" : "Bob") << endl;
    }
    return 0;
}
发布了179 篇原创文章 · 获赞 110 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Q_1849805767/article/details/104300542