[版权说明]
编程之美系列算法题集参考:
左程云 著《程序员代码面试指南IT名企算法与数据结构题目最优解》
July 著《编程之法面试和算法心得》
何海涛 著《剑指offer》
微软编程之美小组 著《编程之美》
部分题目摘选PAT、HDOJ、POJ以及各大互联网公司Google,BAT等面试题集。
博主采用C/C++语言实现(有些题目的解法进行优化)。希望编程之美系列博文没有侵犯版权!(若侵权,请联系我,邮箱:1511082629@nbu.edu.cn )
欢迎大家转载分享,编程之美系列算法题集,会不定期更新。鉴于博主本人水平有限,如有问题。恳请批评指正!
题目1. Bash Game,有一堆石子,总共有n个。两个人轮流从这堆石子取石子。规定每次至少取1个,最多取m个。问什么时候先取的赢?什么时候后取的赢?
【解析】这道题是组合数学中经典的题目,假设先取的人是A,后取的人是B。在这里我们引入一个概念平衡状态,又称作奇异局势。当面对这个局势时则会失败。任意非平衡状态可以经过一次操作可以变为平衡状态。A和B都会努力使自己取完石子后的局势为平衡的,将这个平衡状态留给对方去破坏。因此,A会在初始为非平衡状态中取胜,B能够在初始为平衡的游戏中取胜。我们举个例子来解释,
A胜利情况:假设n=100,m=6;这种情况下A会取得胜利,为什么呢?因为,此时平衡状态就是n%m = 1,A只要保证这个平衡状态成立就可以了, 这时候A应该取3。接下来如果B取的数是x(假设x<m)的,A就取m-x个;如果B取m个,A也取m个,这样就可以保证A胜利。
B胜利情况:假设n=100,m=3;这种情况下B会取得胜利,为什么呢?因为,此时已经达到平衡状态,B只要一直处于平衡状态就可以获得胜利。
题目2. Nimm Game,有k堆石子,每堆有n个石子。两个人轮流从某一堆取任意多的石子。规定每次至少取一个,可以取任意个。取走最后的石头的获胜。问什么时候先取的赢?什么时候后取的赢?
【解析】该题和第1题相似,此题的平衡状态将每堆石子的个数进行求异或,如果异或后为0就为平衡状态。举个例子:
假设一共有3堆,分别为1, 2,3。此时异或的结果为1⊕2⊕3=0。则此时B可以获胜,无论A怎么取,B只要保证取完之后异或的结果为0就可以了。
如果初始的状态异或的结果不为0,A可以获胜,A只要保证每次取完之后,异或的结果为0就可以了。这里不进行详细阐述(因为我忘记如何证明了,组合数学学完全忘记差不多了,博主过于愚蠢)