华为机试--捡石子

昨天去华为机试,前两道都比较简单,最后一道是关于捡石子的问题,当时没想到好的办法解决,8个测试用例只过了6个,回来想了想,想到了一种能解决的方法。

题目:有n(n>=2)个石子,甲乙两个人从这些石子中轮流拿取m(m>=1)个石子,规定第一个拿的人可以拿任意多个,但不能完全拿完,然后,后面的人最多可以拿取前面人的2倍,最后一个拿完石子的人获胜。第一个获胜的人输出1,第二个人获胜输出2。

举例:一共有10个石子,甲先拿,那甲刚开始最少拿1个,最多拿9个(不能拿完)。假如甲拿2个,则乙最少拿1个,最多 拿4个(2的两倍)。若乙拿2个,则甲最少拿1个,最多拿4个。以此类推,直到一方把所有石子都拿完而获胜。

解析:虽然第一个人可以拿任意多个,但是后面的人最多可以拿他所拿石子的2倍,那么第一个人最多不能拿超过总数的1/3,等于1/3也不可以,必须小于1/3。后面的人也是如此。则两个人每次最多拿(n-1)/3,由于最少要拿一个,则每次最多拿 t=max{(remaining-1)/3,1},remaining为剩余石子数量。定义一个一维数组c[0...n](0,1位置不用),数组的第i个元素c[i]表示石子个数为i时胜出的一方(1或者2)。上面已经讲了,一方每次最多拿t=max{(remaining-1)/3,1}个,最少可以拿1个,则每次可以拿count={1...t}个。

讲到这差不多就知道怎么做了。如果现在剩余remaining个,现在拿石子的一方可以拿count(count=1...t)个,则此时拿完count个后,还剩余remaining-count个。由于之前数组c[] 已经保存了c[remaining-count]的大小,也就是胜出一方,则我们可以在remaining-1到remaining-t中寻找是否有2(因为此时代表后边的人先取,如果自己想要赢,寻找的数中必须有2),如果有,则先取的人会赢;否则,后取得人会赢。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值