石子 无限拿
给定 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 先手必败
a1∧a2∧a3...∧an=0先手必败
证明:
0
∧
0
∧
0
∧
0...
∧
0
=
0
a
1
∧
a
2
∧
a
3
.
.
.
∧
a
n
≠
0
begin{align*} 0wedge0wedge0wedge0...wedge0 = 0\ a_{1} wedge a_{2} wedge a_{3}...wedge a_{n} not= 0 \ & end{align*}
0∧0∧0∧0...∧0=0a1∧a2∧a3...∧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
ai∧x<ai , 那么就拿走 少的那一部分。
此时
a
i
=
a
i
∧
x
a_{i}= a_{i} wedge x
ai=ai∧x 带入到原来式子后得到:
x
∧
x
=
0
x wedge x = 0
x∧x=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*}
a1∧a2∧a3...ai∧..∧an=0a1∧a2∧a3...ai′∧..∧an=0式子相异或得ai∧ai′=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 << "Yesn";
else cout << "Non";
}
最后
以上就是阔达大门最近收集整理的关于石子 无限拿石子 无限拿的全部内容,更多相关石子内容请搜索靠谱客的其他文章。
发表评论 取消回复