《编程之美-微软技术面试心得》这本书中的1.11节的转化问题研究:nim拈游戏研究

《编程之美-微软技术面试心得》这本书中的1.11节有一个问题:


一堆石块,A和B两个人从里面拿,每次只能拿一个或者任意连续的两个,最后拿到的算赢,先拿者是否有必胜策略:


这个问题较为简单:先拿者有必赢策略,只要按照如下规则拿即可,如果有奇数个石块,先拿者只拿中间的一个,如果偶数块,先拿者拿中间的两个,之后的策略就很简单了,和对手对称的拿就行了,对手怎么拿,先拿者也怎么拿,一定会拿到最后一块。


现在将问题转化一下,如果最后拿到算输的话,先拿者是否还有必胜策略呢??


如果共有1个石块,有必赢策略

2:有

3:有

4:无

5:有(拿掉边上的一个,就使得对方没有必赢策略)

6:有(拿掉边上的两个)


规则1:如果n没有必赢策略,那么n+1和n+2一定有必赢策略


给定一堆石块n个,怎样判断先拿者是否有必胜策略呢,就是判断从n个石块任意拿一个或者连续的两个,以后的结果如果没有必赢策略,那么这n个石块的堆就有了必赢策略:

用[x,y]表示一个被拆分了的堆,首先计算[x,y]是否有必赢策略。


规则2:n个石块的一段,拿掉任意一个或者连续的两个以后剩下[x,y],如果任意一种情况没有必赢策略,那么n个一堆就有必赢策略,否则,没有必赢策略


规则3:[x,y]是否有必赢策略可以通过和规则2一样的推理方法,又所有[x,y]的拆分情况是否有必赢策略决定。


规则4:初始条件相关,奇数个1的组,有必赢策略,退化为1个1的组,偶数个1,无必赢策略,退化为两个1的组。


使用以上4个规则,则可以得出一个算法:


package shikuai;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;

/**
 * 
 * 一堆石块,A和B两个人从里面拿,每次只能拿一个或者任意连续的两个,最后拿到的算输,先拿者是否有必胜策略
 * 
 * @author wan
 * 
 */

public class ShiKuaiProblem {

	static class ShiKuai implements Comparable<ShiKuai> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值