石子 无限拿

石子 无限拿

给定 n 堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。

问如果两人都采用最优策略,先手是否必胜。

思路

若为 2, 3堆, 先手在3堆里拿1个, 为 2 2。
之后只要跟后手拿的数量相同, 后手一定失败。

定理:
a 1 ∧ a 2 ∧ a 3 . . . ∧ a n = 0 先手必败 a_{1} \wedge a_{2} \wedge a_{3}...\wedge a_{n}= 0 先手必败 a1a2a3...an=0先手必败
证明:
0 ∧ 0 ∧ 0 ∧ 0... ∧ 0 = 0 a 1 ∧ a 2 ∧ a 3 . . . ∧ a n ≠ 0 \begin{align*} 0\wedge0\wedge0\wedge0...\wedge0 = 0\\ a_{1} \wedge a_{2} \wedge a_{3}...\wedge a_{n} \not= 0 \\ & \end{align*} 0000...0=0a1a2a3...an=0
不等于0时, 设结果为 x x x
x x x 的二进制表示为 10100100 10100100 10100100
a i a_i ai的二进制表示 1100100110 1100100110 1100100110
一定存在 a i a_i ai x x x 最高位 k k k 位上为1。
a i ∧ x < a i a_{i} \wedge x < a_i aix<ai , 那么就拿走 少的那一部分。

此时 a i = a i ∧ x a_{i}= a_{i} \wedge x ai=aix 带入到原来式子后得到:
x ∧ x = 0 x \wedge x = 0 xx=0
故先手必赢。

等于0时, 设同样可以拿走一些, 剩下 a i ′ a_i' ai
a 1 ∧ a 2 ∧ a 3 . . . a i ∧ . . ∧ a n = 0 a 1 ∧ a 2 ∧ a 3 . . . a i ′ ∧ . . ∧ a n = 0 式子相异或得 a i ∧ a i ′ = 0 a i = a i ′ \begin{align*} a_{1} \wedge a_{2} \wedge a_{3}. ..a_{i}\wedge..\wedge a_{n} = 0\\ a_{1} \wedge a_{2} \wedge a_{3}. ..a_{i}'\wedge..\wedge a_{n} = 0\\ 式子相异或得 \\ a_{i}\wedge a_{i}' = 0 \\ a_{i} = a_{i}' \end{align*} a1a2a3...ai..an=0a1a2a3...ai..an=0式子相异或得aiai=0ai=ai

代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

int readInt()
{
    int t ;
    scanf("%d", &t);
    return t;
}

int n;
int main()
{
    int x;
    cin >> n;
    cin >> x;
    n -= 1;
    while(n--)
        x ^= readInt();
    if(x) cout << "Yes\n";
    else cout << "No\n";
    
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值