不久前我在谷歌的采访中被问到这个问题,到目前为止,我没有找到一个好的答案: 这是一个2人游戏,你会得到一串零和一个。在每个回合中,玩家可以选择1(或彼此相邻的多个1)并将其/它们更改为0/0。将最后1个(或1个组)更改为0/0的玩家是游戏的赢家。
例如从0101110开始。第一个玩家有7个可能的动作:
目标是如果你先开始就弄清楚是否有获胜策略。 我们在这里假设两位球员都是优秀球员(这意味着他们不会犯错!)
更新 这个游戏与Nim(https://en.wikipedia.org/wiki/Nim)略有不同,对于Nim来说,每个回合的桩数(或堆数)保持不变,而在每一个回合中你都可以改变桩的数量。 例如,如果我们做0101 1 10 - > 0101 0 10最初我们有两个大小为1和3的桩,但在移动后我们将有3桩,大小为1。
答案 0 :(得分:1)
让nim[n]
成为n
序列的nimber。然后我们有以下递归关系:
nim[n] = mex{nim[i] xor nim[j]: i, j >= 0, i + j < n}
(有关一般理论,请参阅Sprague-Grundy theorem。)
从这个递归关系中,您可以尝试计算序列nim
的前几个项,您会发现它似乎nim[n] = n
。
然后可以很容易地推断出证明,我将留给你。
因此,n
连续序列的序列实际上等同于大小为n
的Nim桩。现在很容易找到任何游戏的结果。
例如,如果我们有0101110
,那么它相当于两堆Nim,分别为1
和3
。因此,总的nimber等于1 xor 3 = 2
,这是非零的,所以第一个玩家获胜。
另一个例子,如果我们有1110011111000111111
,那么总的nimber等于3 xor 5 xor 6 = 0
,所以第一个玩家输了。
编辑:关于桩的变化的问题,这里有一些更多的解释。
虽然桩的数量会发生变化,但关键点如下:
因此对于胜利者来说,策略是给对手留下零点状态。
示例:让我们从序列1110011111000111111
开始,我简称为3, 5, 6
。
如果第一位玩家将6
替换为2
和3
的总和,则第二位玩家将面临状态3, 5, 1, 4
,其状态为3 xor 5 xor 2 xor 3 = 7
}。为了使其保持为零,第二个玩家将5
替换为2
,留下第一个玩家3, 2, 2, 3
,它再次为零。
程序继续,直到第一个玩家没有有效的移动。
答案 1 :(得分:0)
可以使用图形表示来解决。
顶点将是给定二进制字符串的可能组合/带二进制的整数 - &gt;十进制转换。
每个顶点都应该有一个连接到顶点的边,其值可以通过制作1 - &gt;来获得。 0根据游戏规则进行转换。
在这种情况下,7位=&gt; 2 ^ 7 = 128种组合。 我们仍然可以过滤掉给定初始组合中永远无法达到的顶点。
例如,
0101110 - &gt; 0 0 01110 - &gt; 0000000(第二位玩家获胜)
0101110 - &gt; 010 0 110 - &gt; 0100 00 0 - &gt; 0000000(第一位获胜者)
它继续这样下去。在每次移动中,我们可以通过获取相邻顶点来识别下一个可能的组合,并将它带到我们一直到获胜组合(0000000)