零和一的游戏(谷歌访谈)

时间:2016-03-11 02:14:57

标签: algorithm math

不久前我在谷歌的采访中被问到这个问题,到目前为止,我没有找到一个好的答案: 这是一个2人游戏,你会得到一串零和一个。在每个回合中,玩家可以选择1(或彼此相邻的多个1)并将其/它们更改为0/0。将最后1个(或1个组)更改为0/0的玩家是游戏的赢家。

例如从0101110开始。第一个玩家有7个可能的动作:

  1. 0 1 01110 - > 0 0 01110(第二位玩家可以获胜)
  2. 010 1 110 - > 010 0 110(第二位玩家可以获胜)
  3. 0101 1 10 - > 0101 0 10(第二名球员可以获胜)
  4. 01011 1 0 - > 01011 0 0(第二位选手可以获胜)
  5. 010 11 10 - > 010 00 10(第一名球员可以获胜)
  6. 0101 11 0 - > 0101 00 0(第一名球员可以获胜)
  7. 010 111 0 - > 010 000 0(第二位玩家可以获胜)
  8. 目标是如果你先开始就弄清楚是否有获胜策略。 我们在这里假设两位球员都是优秀球员(这意味着他们不会犯错!)

    更新 这个游戏与Nim(https://en.wikipedia.org/wiki/Nim)略有不同,对于Nim来说,每个回合的桩数(或堆数)保持不变,而在每一个回合中你都可以改变桩的数量。 例如,如果我们做0101 1 10 - > 0101 0 10最初我们有两个大小为1和3的桩,但在移动后我们将有3桩,大小为1。

2 个答案:

答案 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,分别为13。因此,总的nimber等于1 xor 3 = 2,这是非零的,所以第一个玩家获胜。

另一个例子,如果我们有1110011111000111111,那么总的nimber等于3 xor 5 xor 6 = 0,所以第一个玩家输了。

编辑:关于桩的变化的问题,这里有一些更多的解释。

虽然桩的数量会发生变化,但关键点如下:

  • 如果状态为nimber为零,则任何有效的移动都必须将其更改为非零的nimber状态。
  • 如果状态为非零nimber,则必须存在有效​​移动,将其更改为零nimber状态。

因此对于胜利者来说,策略是给对手留下零点状态。

示例:让我们从序列1110011111000111111开始,我简称为3, 5, 6

如果第一位玩家将6替换为23的总和,则第二位玩家将面临状态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)