`

编程之美-NIM游戏分析-石头总数为奇数时如何保证先动手者必胜

 
阅读更多


import java.util.Arrays;
import java.util.Random;

public class Nim {

	/**编程之美 NIM游戏分析
问题:
有N块石头和两个玩家A和B,玩家A先将石头随机分成若干堆,然后按照BABA...的顺序不断轮流取石头,
能将剩下的石头一次取光的玩家获胜,每次取石头时,每个玩家只能从若干堆石头中任选一堆,
取这一堆石头中任意数目(大于0)个石头。
请问:
玩家A要怎样分配和取石头才能保证自己有把握取胜?

1.如果石头的个数N为偶数,A只要将其分为相同的两份,就一定能取胜。
初始:XOR(M1, M1) == 0
玩家B:XOR(M1, M2) != 0  (其中一堆的个数减少到M2)
玩家A:XOR(M2, M2) == 0  (玩家A将另一堆的个数也减少到M2)
结果:XOR(M2, M2) == 0  (直到结束状态(0, 0))

2.如果石头的个数N为奇数,B有必胜的方法。
初始:XOR(M1, M2, ... , Mn) != 0
玩家B:XOR(M1, ... , Mi', ... , Mn) == 0 (其中一堆Mi的个数减少到Mi')
玩家A:XOR(M1, ... , Mj', ... , Mn) != 0
玩家B:XOR(M1, ... , Mi', ... , Mn) == 0 (其中一堆Mi的个数减少到Mi')
结果:XOR(M1, ... , Mj' , ... , Mn) == 0 (直到结束状态(0,0))

这里就有个问题:已知XOR(M1, M2, ... , Mn) != 0,玩家B该改变那个Mi以使得XOR(M1, ... , Mi', ... , Mn) == 0呢

刚开始我的思路是基于以下结论:
1.Mi改变成Mi'后,如果数组可以分成和相等的两部分,那么数组所有元素异或的结果一定是0
--这个结论是错的,例如2^7^9=12,尽管9^(2+7)=0
2.Mi=max(M1,M2...Mn) 
--这也是错的。从max里面取走x块石头与非max里面取走x块石头,结果是不一样的
--例如(9,7,9),取走7块石头,有两种情况:XOR(9,0,9)=0; XOR(2,7,9)=12

正确的思路:
令xor=XOR(M1,M2,...Mi-1,Mi,Mi+1,...Mn);
Mi'=Mi^xor=XOR(M1,M2,...Mi-1,Mi+1,...Mn)
那么XOR(M1,M2,...Mi-1,Mi',Mi+1,...Mn)=0
	 */
	public static void main(String[] args) {
		int numOfHeap=5;	//石头堆数
		for(int i=0;i<10;i++){		//测试10次
			int[] stones=generateStones(numOfHeap);
			process(stones);
			System.out.println("=================================");
		}
		
	}
	
	//当前石头总数为奇数时,如何取石头才能使自己必胜(即使异或结果为0)
	public static void process(int[] a){
		
		if(a==null||a.length<2){
			return;
		}
		
		int size=a.length;
		int xor=0;
		for(int i=0;i<size;i++){
			xor ^=a[i];
		}
		
		if(xor==0){		//数组和(石头总数)为奇数,则不管怎么分堆,分堆的异或结果一定不是0。其他情况不在本次讨论范围内
			return;
		}
		
		int i=0;
		int diff=0;
		int mi=0;
		for(;i<size;i++){
			mi=a[i]^xor;
			if(a[i]>=mi){
				diff=a[i]-mi;
				break;
			}
		}
		
		System.out.println(Arrays.toString(a));
		System.out.println("now you should take "+diff+" stones from a["+i+"]="+a[i]);
		
		//验证一下现在异或结果是不是0
		a[i]=mi;	//取走石头
		xor=0;
		for(int x:a){
			xor ^=x;
		}
		System.out.println("XOR"+Arrays.toString(a)+"="+xor);
		
	}
	
	private static Random random=new Random();
	
	//产生指定堆数的石头数组,且保证石头总数为奇数
	public static int[] generateStones(int numOfHeap){
		if(numOfHeap<2){
			return new int[0];
		}
		int[] stones=new int[numOfHeap];
		int sum=0;
		for(int i=0;i<numOfHeap;i++){
			stones[i]=random.nextInt(10)+1;
			sum +=stones[i];
		}
		if(sum%2==0){	//保证石头总数为奇数
			stones[0] +=1;
		}
		return stones;
	}
}

0
9
分享到:
评论

相关推荐

    NIM(2)“拈”游戏分析

    ### NIM(2)“拈”游戏分析 #### 背景介绍 “拈”游戏是一种源自中国的传统博弈游戏,其英文名"NIM"来源于粤语中的“拈”(意为“取”)。在游戏中,参与者需要运用策略来赢得比赛。本篇文章将详细探讨“拈”游戏...

    matlab开发-NIMgame

    在这个名为"MATLAB开发-NIMgame"的项目中,我们关注的是利用MATLAB构建一个NIM游戏的图形用户界面(GUI)。NIM游戏是一个经典的数学游戏,通常涉及到玩家之间的策略和逻辑推理。 NIM游戏规则相对简单,但具有深度。...

    acm算法-nim游戏篇(算法设计)

    A number of Nim-like games in which moves are restricted somehow to occur from a single pile are analysed. In each case the complete description of type P and type N positions is obtained. A more ...

    Atom-nim-planet,nim rss feed planet网址:https://planet.nim.zip

    标题中的“Atom-nim-planet”指的是一个与Nim编程语言相关的RSS聚合平台,它将来自不同来源的Nim相关的博客、新闻和其他更新整合到一个地方,方便社区成员跟踪和了解Nim语言的最新动态。这个平台的网址是...

    hts-nim-tools:有用的命令行工具,用于展示hts-nim

    hts-nim-tools 是一个基于 Nim 语言的命令行工具集合,主要服务于生物信息学领域,特别是针对基因组学数据的处理。Nim 是一种现代、高性能的编程语言,其语法简洁,编译效率高,适合开发这类对计算速度有较高要求的...

    nim-nim.zip_nim

    【标题】"nim-nim.zip_nim" 指的是一个与 Nim 语言相关的压缩文件,其中包含了名为 "nim" 的文件。Nim 是一种现代、静态类型、编译的系统编程语言,设计目的是高效、灵活且易于学习。它借鉴了多种语言的特点,如 ...

    c语言入门编程之数学问题Nim游戏.zip

    本压缩包“c语言入门编程之数学问题Nim游戏.zip”显然旨在帮助新手通过解决实际问题来学习C语言。Nim游戏是一个经典的数学和逻辑思维游戏,它在编程教学中常被用来教授条件语句、循环结构以及基本算法设计。 Nim...

    Orbits-nim的轨道力学库。_Nim_C_下载.zip

    Orbits-nim是一个基于Nim编程语言的轨道力学库,主要设计用于模拟天体运动,如行星、卫星等在重力作用下的轨迹计算。Nim是一种现代、静态类型的系统编程语言,它结合了C的效率和Python的简洁性,使得Orbits-nim库...

    space-nim:用于学习Nim编程的基于文本的太空游戏

    "space-nim" 不仅仅是一款游戏,它是一个综合的学习平台,为想要掌握 Nim 编程语言的初学者提供了丰富的学习资源和实践经验。通过这种方式,学习者可以在娱乐中进步,提高编程技能,并享受编程的乐趣。

    AIX-NIM

    AIX-NIM作为AIX操作系统的核心管理工具之一,为IT专业人员提供了强大且灵活的网络安装和管理系统。通过深入理解其工作原理、掌握新特性和优化配置策略,企业可以显著提升AIX系统的部署效率和管理效果,同时降低运维...

    计算机系统1 实验四、五 Nim游戏 汇编源码

    计算机系统1 实验四、五 Nim游戏 汇编源码 计算机系统1 实验四、五 Nim游戏 汇编源码 计算机系统1 实验四、五 Nim游戏 汇编源码 计算机系统1 实验四、五 Nim游戏 汇编源码 计算机系统1 实验四、五 Nim游戏 汇编源码 ...

    godot-nim:Godot Engine的Nim绑定

    而godot-nim是将Nim编程语言与Godot Engine结合的项目,为Godot提供了Nim语言的绑定,使得开发者可以利用Nim的强大特性来编写Godot游戏。 Nim是一种现代的、静态类型的、命令式的、编译型的语言,设计目标是高效、...

    zwangZJU#LeetCode-in-python-wznote#LeetCode-python-292-Nim-游戏1

    解题思路如果最后剩下1-3个石头,你肯定是赢家,如果此时剩下4个石头,你无论拿多少个,对方一定会赢。如果此时剩下5个石头,这时你的最佳策略是拿走一个石头,这是对

    c-terminal-nim:可以用终端机玩的用C语言编写的Nim游戏

    C Terminal Nim有一个不言而喻的名称:这是您可以在终端中玩的Nim游戏。 目前,只有本地两人游戏模式可用。 指示 正在下载 导航到发行页面,并下载适用于您系统的二进制文件(对于Linux是nim ,对于Windows是nim....

    Game-of-Nim

    在 `Game-of-Nim-main` 文件中,我们可能看到以下内容:主函数 `main` 负责启动游戏,调用 `NimGame` 类的实例来处理游戏逻辑。游戏循环会持续到游戏结束,期间不断与用户交互,获取并处理玩家的移动。代码中可能...

    feed-nim:Nim的提要解析模块

    总的来说,feed-nim为Nim开发者提供了一个强大的工具,使他们能够在处理各种提要格式时保持高效和灵活,从而在开发新闻聚合应用、数据分析系统或其他需要提要数据的项目中发挥关键作用。通过熟练掌握feed-nim,...

    JAVA小游戏nim系统

    【JAVA小游戏nim系统】是一个基于Java编程语言实现的智力挑战游戏,它被称为“nim”游戏。nim游戏源自一种古老的策略游戏,通常涉及玩家之间交替移除物体,目标是避免成为最后一个移除物体的人。在这个Java版本中,...

    msgpack-rpc-nim:Nim 的 MessagePack-RPC 实现

    **msgpack-rpc-nim** 是一个专门为 Nim 语言实现的 MessagePack-RPC(Remote Procedure Call)库。Nim 是一种静态类型、编译型、系统级编程语言,设计目标是提供高效的代码、强大的语法和现代编程理念。MessagePack-...

    napi-nim:在Nim中编写NodeJS本机扩展

    在Nim中编写NodeJS本机扩展 如果您不喜欢C代码的冗长且感到C ++太复杂,请尝试使用napi-nim来提高NodeJS应用程序的性能。 现在是NodeJS一部分的新n-api使您可以与支持C ABI的任何语言JavaScript代码进行交互。 是...

    Nim-示例:开始进行Nim编程时,我正在制作一些简单的示例

    在这个名为"Nim-Examples"的压缩包中,你可能会找到一系列用于初学者的Nim编程示例,帮助你快速上手并熟悉这种语言。 1. **语法基础**: - Nim的语法灵感来源于C、Python和ML,因此对于熟悉这些语言的开发者来说很...

Global site tag (gtag.js) - Google Analytics