首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >2/9游戏(在Facebook接受采访)

2/9游戏(在Facebook接受采访)
EN

Stack Overflow用户
提问于 2012-11-13 16:40:15
回答 9查看 3.2K关注 0票数 12

有人问我这个问题:谷歌的相似问题。Facebook在接受采访时也提出了类似的问题。

2/9数字游戏的胜利者 两名玩家玩以下游戏:他们选择一个随机数N(小于20亿),然后,从1开始,将上一轮的数字乘以2或9(他们的选择)。先到N的人就赢了。 候选人应该编写一个函数,给出N来决定谁赢(第一名还是第二名?)

对于乘法来说,基本的随机选择2/9会起作用吗?否则他们会希望我们在做动作时增加智慧。对于例:从乘法开始用2,乘法用9,只有当你看到别人不能比你更快到达N?

处理这类问题的最佳方法是什么?

EN

回答 9

Stack Overflow用户

发布于 2012-11-14 07:15:26

解决这类问题的最佳方法。

首先,你需要对游戏理论的有基本的理解,。很基本的。这就是你意识到的事实,对于一个给定的数字N,对于首发球员有一个获胜策略,或者对他的对手有一个制胜策略。因此,你必须假设他们都知道策略,并发挥他们所能做的最好的动作。

然后开始使用,熟悉的游戏。你在低水平上练习。你很快就会注意到,在2-9的比赛中,先发就赢了,而在10胜18负的情况下,他必须输掉.因此,您的函数已经为N<=18的情况做好了准备。

然后你开始考虑的一般获胜策略,。知道策略会给你算法。5分钟后(越快越好),你就会明白你不能及时找到获胜的策略,因为在这种情况下并不明显。所以你决定给计算机一些基本原理,让它为你解决这个难题。你知道你会使用递归。

您试图找到递归的规则。你可能想从结尾或开始开始。我将从最后描述这个方法。

这场比赛的目标是把你的对手推到那个区域,在那里他必须给你胜利。而不是自己被逼到那个区域。从N/9到N有一个获胜的区域。如果一个人被逼在N/9/2和N/9之间打球,他一定会输。(因为他的两个动作都把他的对手推到了制胜区。)所以你写你的函数:

代码语言:javascript
复制
wins(n) {
  // returns 1, if starting player is able to reach
  // the range [n, 2*n) with his move
  if (n<=18) {
    if (n<=9)
      return 1;
    else
      return 0;
  } else {
    // I must push him to the zone between N/9/2 and N/9
    return wins(n/18);
  }

如果你到了那个地步,你就通过了。还有一些细节,比如是使用float还是int,还是使用int来整整。但总的来说,你表现出了正确的思维方式,你已经准备好面对面试官了:)

编辑:实际上,上面的代码中有一个错误。“胜利”与“能够到达范围(n,2n)”是不一样的。这里可能需要两个函数:wins(n)reaches_slightly_above(n)__。后者将以递归方式调用,在18以下返回的值应该是不同的,类似于https://stackoverflow.com/a/13367642/772981解决方案中的值。但是,下面的解决方案和一般方法应该是可以的。

从下到上的替代方法是使用以下函数:

代码语言:javascript
复制
wins(a,n) {
  if (9*a >= n)
    // I win easily
    return 1;
  else
    // if one of my moves pushes the opponent to the zone
    // where he's not able to win, then I win!
    return !wins(2*a, n) || !wins(9*a, n);
}

如果他们要求n,则返回win(1,n)的值。这个算法的复杂性并不明显,但我相信它是对数的。

票数 9
EN

Stack Overflow用户

发布于 2012-11-13 17:37:49

因为它们必须精确地到达N,所以只有当N2^a * 9^b形式时才有可能,其中一个a, b也允许为0。

在上面找到ab:如果是a + b = even,那么第二个玩家就会赢,否则第一个会赢。

这是因为,在每一步中,玩家都会一步一步地接近ab,因此也就会一步一步地接近a + b。因此,问题归结为:给定k,如果玩家在每一步都必须从k中减去1,那么哪个玩家将首先达到0?

票数 6
EN

Stack Overflow用户

发布于 2012-11-13 19:46:58

最佳的比赛通常是与对手的移动相反,除了在开始和结束的时候。

通过与递归解决方案的比较,可以根据数字-1的基数18表示中最重要的数字计算出答案如下:

代码语言:javascript
复制
def win29(n):
    if n<=9: return True
    n-=1
    while n>=18:
        n = n//18
    return n==1 or 4<=n<=8
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13364811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档