LeetCode之路:292. Nim Game

一、引言

这是一道非常有趣的题目,有着非常简单的规则,却让我一直没有思考出来,甚至在思考这个问题的同时,还引申到了另一道题上面:台阶问题:斐波那契数列的扩展问题研究,有兴趣了解下的同学可以看看这里。

关于这道题,其实这是一个非常出名的游戏,有着不同的版本,LeetCode上面的这个题目是简化的版本。

这里直接把原题目粘贴过来:

You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.

Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.

For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.

那么,这道题怎么做呢?

二、让我们来一个一个例子分析下这个情景

首先,我们来一个一个举例,举例的过程中,我们要记住,每人最多拿 3 个石头,最少必须拿 1 个石头:

当前的石头总数先手取多少必胜后手是否必败
11必败
22必败
33必败
41 ~ 3必胜
51同4个石头的情况类似,只不过先后手更替,此处先手必胜
62同4个石头的情况类似,只不过先后手更替,此处先手必胜
73同4个石头的情况类似,只不过先后手更替,此处先手必胜
81 ~ 3此时不论先手拿多少个,都可以让后手造成先手4个石头总数开局,先手必败

看上面这个表,我们能看到这么一个规律:

当先手玩家遇到了非4的倍数,可以确保必胜;当先手玩家遇到了4的倍数的时候,后手玩家拿走指定数量的石头数量造成剩余4的倍数的石头数量后,后手玩家必胜。

规律总结出来了,真的非常简单,以至于代码更加简单:

class Solution {
    bool canWinNim(int n) {
        if (n % 4 == 0) return false;
        else return true;
    }
}

哈哈哈,看到了更简单的方法:

class Solution {
    bool canWinNim(int n) {
        return n % 4;
    }
}

真是好气啊~~~我思考了这么久都没想出来的问题呢,一行代码解决!

三、总结

其实我一看到这道题,脑海里第一个念头是,怎么跟台阶问题那么像,比如:

有一只青蛙,它一次可以跳 1 阶或者 2 阶台阶,那么请问它跳上 N 阶台阶有多少种走法?

这个问题呢,其实是探讨的石头的拿法,但是这道题并不需要拿法有多少,只需要总结规律是否必胜就行了。

总之,学会分析问题的方法。

To be stronger!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值