蓝桥杯考试 尼姆堆

题目

有3堆硬币,分别是3,4,5
二人轮流取硬币。
每人每次只能从某一堆上取任意数量。
不能弃权。
取到最后一枚硬币的为赢家。


求先取硬币一方有无必胜的招法。

分析:任何无偏博弈游戏都可以转换为尼姆堆 求解尼姆堆的方法为 将每个堆转换为二进制并且异或 如果结果为0则此时先手的必输。即当结果为0时为P态,否则为N态,我们的目标就是,判断现在是不是P态,如果是,则我们必输,如果不是,那我们把其从N态变为P态。变得方法就是让贡献最高位的数字变小使得结果为0.

例如 堆此时为2,5,12,14

分别转化为二进制 异或

0010

0101

1100

异或1110

---------------

        0101

  ↑  贡献最高位的那些数字就应该变小    使得结果为0 则对手输

结果 (2)101--->0             5变为0

 (3)1100-->1001     12变为9

 (4)1110-->1011      14变为11

代码中运用的方法为  a^b^c...==K 则K^a = b^c^....

public class _4_数学_03尼姆堆 {

	static int[] arr = {2,5,12,14};	//尼姆堆
	
	public static void nimu(int []arr)
	{
		int [] temp = new int[arr.length]; 	
		for(int i=0;i<arr.length;i++)
			temp[i]=Integer.parseInt(Integer.toString(arr[i],2));	//依次将尼姆堆中的每个数据都转为2进制并存入temp
		int x = 0;													//异或结果
		for(int i=0;i<arr.length;i++)								//依次异或
			x=x^arr[i];
		System.out.println(Integer.toString(x,2));					//输出异或结果的二进制
		for(int i=0;i<arr.length;i++)
		{
			if((x^arr[i])<arr[i])									//依次异或每个数,看是不是比原数字小
			System.out.println(arr[i]+"--->"+Integer.toString(x^arr[i]));	
			//a^b^c^d = K 将b^c^d看作整体 是因为有了a才会使k不等于0 则如果a=k 则结果为0 
		}
	}
	public static void main(String[] args) {
		nimu(arr);
	}
}







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值