算法一千零一夜 · 第九夜 卖火柴的小女孩的游戏

发布时间:2026/10/19 4:25:10

算法一千零一夜 · 第九夜 卖火柴的小女孩的游戏 第九夜 · 卖火柴的小女孩的游戏第九夜让我们走进安徒生童话听听他笔下卖火柴小女孩与大年夜游戏的故事。篮子里还剩三十一支火柴我数了三遍。数目越数越清楚天却越来越黑。大年夜的雪落个不停街两旁的窗户一格一格地亮起来窗里全是热的烤鹅和热面包的香气从窗缝里挤出来。只有我站在墙角光着两只脚雪把脚背一点一点盖住。火柴一支也没有卖掉。一整天我等在街角看大人的靴子一双一双从我面前掠过去没有一双停下来。我学会了看人。赶着回家的不买手挽着手说笑的不买酒气熏熏大声吆喝的更不买。天黑透了我不敢回家火柴没有换成钱回去父亲要打我的。再说家里跟街上一样冷屋顶上只有一层破草毡最大的裂缝拿草和破布堵着风照样灌进来。祖母在的时候冬天晚上我不用上街。屋里冷得早祖母舍不得点灯就抓一把火柴摊在桌上跟我玩游戏。她把火柴分成几堆我们轮流拿谁拿到最后一支谁赢。她教过我一句口诀数目是要成双的把落单的留给对手。跟我说这话的时候她在桌上画了下面这张图。我那时看不大懂那些一和零只记得清清楚楚图上每一对一都被弧线牵在一起谁也不落单。跟着这张图摆摆着摆着桌上的火柴就全到了我手里。祖母夸我说这双手将来饿不死。祖母是去年冬天走的走的那晚也下着雪。一双大靴子在我的篮子前面停住了。我抬起头是一位先生呢子大衣领子上落着雪眉毛也是白的。他蹲下来蹲得跟我一般高声音放得很轻。他问孩子这么晚了怎么还不回家。我说火柴没有卖掉不敢回去。他从口袋里摸出几枚铜板说火柴我全要了不用找了。我把篮子往怀里收了收摇头。祖母说过钱要凭本事挣白给的钱拿在手里跟讨来的一样。他捏着铜板愣在那里大概没有想过一个卖火柴的小女孩还会摇头。我看看他又看看篮子心里有一个主意冒出来。我说先生我们玩个游戏吧。我从篮子里数出六支火柴摆在两人中间的石阶上一堆一支一堆两支一堆三支。我们轮流拿每次只许从同一堆里拿拿几支随便不许不拿谁拿到最后一支火柴谁就赢了。您赢了这六支白送您篮子里剩下的也白送。我赢了您把火柴全部买走一枚铜板一支公道价。他说要是我不玩呢。我说那火柴还在这儿您走您的路。他笑了把我从头到脚打量了一遍又看了看那三小堆火柴像大人看小孩掏出一件宝贝。他说好依你。他顿了顿又说局是你摆的我先拿这总公道了吧。我说本该如此。客人先请。他从最长那堆里抽走一支在指头上转了转漫不经心的像在等我后悔。三堆成了一支、两支、两支。我盯着石阶上的三堆祖母的口诀在心里走了一遍。我把单着的那一堆收进掌心桌上剩下两堆每堆两支。他愣了一下又从方才那堆抽走一支。一堆两支一堆一支。我把两支那堆收走一支。桌上剩下一支、一支齐齐的一对。他抽走其中一支。最后一支火柴立在雪地上孤零零的。我伸手把它拿了起来。他把六支火柴拢在掌心数了一遍又数了一遍蹲在那里把三堆重新摆回一支、两支、三支自己跟自己走了一遍走一步停一停眉头越皱越紧。走完他把火柴一拢说再来一把。我说说出去的话要作数。他不说话了。街上安静雪落下来有细细的声音。过了一会儿他数出六枚铜板一枚一枚码在石阶上又指了指我的篮子问还剩多少。我说二十五支。他说一并算上。三十一枚铜板全放在我的手心里压得手腕往下一沉。他问谁教你的。我说祖母。他说替我谢谢她。我张了张嘴没有说祖母已经不在了。我说好。我往家跑。铜板在口袋里叮叮当当地响像一小串过年的铃铛。窗户里的灯还是那么亮烤鹅的香气还是那么浓可是从前它们是别人的今晚起也算我的一份。雪还在下落在脸上不冷了。祖母说过火柴划一支就少一支玩法却不会你把它讲给别人听它就一直亮着。今晚我把它讲给一位先生听了。往后每一个大年夜他都会记得有一年雪夜他输给过一个卖火柴的小女孩输得心服口服还替她把三十一支火柴全数买走。火柴卖完了。祖母的玩法从今晚起也在别人那里亮着了。public class MatchGame { // 桌上所有堆一起做异或得出这一手的局面值 static int nimSum(int[] piles) { int x 0; for (int p : piles) { x ^ p; } return x; } // 祖母口诀的机器版局面值为零轮到走的人必败 // 必胜的一手挑出一堆拿走若干支把局面值送回零 static int[] zeroMove(int[] piles) { int x nimSum(piles); for (int i 0; i piles.length; i) { int keep piles[i] ^ x; if (keep piles[i]) { return new int[]{i, piles[i] - keep}; } } return null; } public static void main(String[] args) { int[] piles {1, 2, 3}; System.out.println(start A1 B2 C3, xor nimSum(piles) , first player must lose); // 先生第一手从最长那堆抽一支 piles[2] - 1; print(man, piles); while (piles[0] piles[1] piles[2] 0) { // 小女孩接招把零找回来 int[] mv zeroMove(piles); piles[mv[0]] - mv[1]; print(girl, piles); if (piles[0] piles[1] piles[2] 0) { break; } int i 2; while (piles[i] 0) { i--; } piles[i] - 1; print(man, piles); } System.out.println(last stick taken by girl); } static void print(String who, int[] p) { System.out.println(who - A p[0] B p[1] C p[2] , xor nimSum(p)); } }① 真伪核对逐条照实登记。Ⅰ Nim 定理 任取若干堆火柴两人轮流从其中一堆取至少一支取到最后一支者胜。把所有堆的支数一起做异或结果是零则轮到走的人必败非零则轮到走的人必胜。此判定即 Nim 定理由查尔斯·布顿Charles L. Bouton1901 年在《数学年刊》第二编第三卷首次发表论文题目直译为《Nim一个有完整数学理论的游戏》载于该卷 35 至 39 页真。布顿时在哈佛大学真。Ⅱ 词源 布顿本人未解释 Nim 一名的来历。通行说法是德语动词 nehmen 的命令式 nimm意思是拿牛津英语字典持此说布顿早年留学莱比锡通德语真。另有一说是古英语废动词 nim拿、窃真两说并存。至于 Nim 倒过来拼正是 win 一节属后世趣谈无出处可考不入正文登记备查。Ⅲ 祖母的口诀与异或 口诀说数目是要成双的把落单的留给对手。它的原理是把每堆支数写成二进制之后逐位配对真。一支、两支、三支写成 01、10、11两个数位上各自恰好有两个一双双成对合起来异或得零真。定理保证从成双局面出发任何一手都会拆散某一双对手从零局面走一步必得非零而轮到守局的人总能再配成一对非零局面必存在一步归零。所以先落在成双局面里的人必败真。本夜正文的 1、2、3 正是这样一手成双局先拿的先生无论怎么取守局的人总走得出下一步成双实跑见 Ⅴ。Ⅳ 安徒生原作 《卖火柴的小女孩》丹麦语原题 Den lille Pige med Svovlstikkerne1845 年 12 月发表真。原作故事发生在大年夜即 12 月 31 日一年的最后一夜通行中译即作大年夜真。破草毡屋顶、裂缝堵草、光脚、墙角擦火柴、烤鹅香气均为原作细节真。原作里祖母早在故事之前就已过世只在火柴的光里出现过一回本夜沿用祖母已故的设定生前教火柴游戏一段为编编。路人、游戏与火柴买卖的结局皆为本夜改编编。Ⅴ 实跑记录 本夜 Java 程序两件JDK 21。其一正文所载 MatchGame六手全程照排先生三手各取一支守局三手逐一归零最后一支落在守局人手里与正文逐句对上。其二NimGame 收在随书代码库三笔验证全数通过两堆三堆支数各不超过十五的全部 4352 个局面异或判定与机器一步一步试出来的胜负完全一致无一分歧两堆到四堆、支数十五以内的随机一千零一局该先手时先手该让先手时让先手守局打法未输一局祖母配对图的 1、2、3 三堆异或得零先手必败与图 9-1 相符。② 今夜习题三道评论区见。Ⅰ 那位先生回家越想越不服第二天摆了三堆火柴请他侄子先拿这回是一支、两支、四支。先拿的人是赢是输写一段代码算一算再找出必胜的第一手看看它摆出来的是个什么局面。Ⅱ 随便取两个不同的数当两堆支数再把第三堆摆成这两堆支数的异或。用代码验证这样摆出来的三堆先拿的人必败。再想一想这是为什么。Ⅲ 后来那位先生自己也学乖了。又一个雪夜他摆了四堆火柴一支、两支、四支、七支请小女孩先拿。小女孩看了一眼说还是您先请吧。写代码算一算这四堆的局面值说说她为什么让。你算出来了吗评论区见。答案与参考程序收在书后《参考解答》。本书目录导航上一篇第八夜 switch 穿透的魔法 让一版受伤的代码成为了断臂的维纳斯 下一篇第十夜 方程之业 起点卷首语·算法童话版权声明本文为作者原创受著作权法保护。未经授权禁止转载、搬运、摘编、改编及任何形式的二次创作个人学习引用请注明作者与原文出处。转载授权请联系作者CSDN 私信。侵权必究。
延伸阅读

更多相关文章

2026/10/19 4:25:10

LangChain进阶实战:自定义Chain与Agent构建复杂AI工作流

1. 为什么我放弃了“拼积木”式的现成Chain接触LangChain的人,大概率都经历过这样一个过程:刚开始觉得这东西太方便了,LLMChain、RetrievalQA、ConversationChain,文档里示例一抄,一个能跑的回答机器人就出来了。但真到…

2026/10/19 4:20:10

Pulsar与Presto集成实战:构建实时可查的流式虚拟表

1. 项目概述:为什么要把 Pulsar 和 Presto 拉到一张表上干活?“Pulsar集成presto”这六个字,乍看像两个技术名词的简单拼接,但背后是一条真实存在的、高频发生的工程痛点链路:某公司实时风控系统每天要处理200亿条用户…

2026/10/19 4:20:10

JavaScript Tab栏切换效果:语义化、性能与可访问性实战

1. 项目概述:为什么一个Tab栏切换效果值得花时间深挖?“JavaScript-Tab栏切换效果”这八个字,看起来平平无奇,像是前端新手入门练习册里第3页的课后题。但在我带过的几十个前端实习项目、参与评审过的上百份求职作品中&#xff0c…

2026/10/19 5:30:16

MySQL日期函数DATE_ADD与DATE_SUB深度解析:语法、边界与索引优化

1. 为什么 DATE_ADD 和 DATE_SUB 值得单独拿出来写做后端开发的,几乎没有不跟日期时间打交道的。订单要算超时时间,会员要算到期日,报表要按天、按周、按月汇总,这些场景全绕不开一个操作——在某个时间点上加一段间隔&#xff0c…

2026/10/19 5:30:16

从互联网泡沫到AGI热潮:技术突破与资本炒作的分界线

我入行那一年,正好赶上上一轮科技周期的尾声。那时候互联网的故事讲得天花乱坠,仿佛谁不站上这趟车,谁就要被时代淘汰。结果泡沫破裂的时候,大家才发现,真正留下来的不是造概念最多的那批公司,而是把网络变…

2026/10/19 5:30:16

深入理解继承:从核心概念到实战避坑指南

1. 为什么继承这件事值得单独拎出来讲刚入行那会儿,我对继承的理解就停留在“子类 extends 父类,然后就能用父类的方法了”这个层面。直到有一次做一个订单系统的重构,我才真正意识到继承这件事远没有想象中那么简单。当时系统里有普通订单、…

2026/10/19 5:30:16

Spark+HBase地铁客流分析:从CSV到分时报表完整链路

简介:一套基于Spark的地铁大数据客流分析系统毕业设计源码包,面向计算机相关专业学生、大数据初学者及毕业设计选题者,围绕地铁客流统计、预测与调度优化场景展开。压缩包共194个文件,约42.6MB,按功能分为Java/Scala核…

2026/10/19 5:30:16

VS工具集实战:环境配置、脚本使用与工程模板生成指南

简介:VS平台工具集.zip是一份面向Visual Studio开发者的平台工具集整合包,用于补充和更新VS的构建与编译组件,适合需要在Windows环境开展.NET/C开发、自定义MSBuild构建流程或调试工具链的工程师。压缩包共收录2000个文件,以1158个…

2026/10/19 5:25:16

C++享元模式实战:从原理到线程安全实现与内存优化

1. 内存告警背后的元凶:上千种弹道特效的重复建模先说个我遇到过的真实场景。某客户端的战斗模块里有一批弹道特效,每个子弹发射后都会在场景里生成一条轨迹,轨迹上挂着一串光点数据。最初功能跑得好好的,但等特效种类从十几个涨到…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/19 0:04:56

悟空开源无代码平台实战:从实体建模到应用设计避坑指南

简介:基于悟空开源无代码平台的多种应用设计源码,面向希望在不编写代码的情况下快速搭建CRM、HRM、财务系统、ERP、SRM等业务应用的企业与技术人员,通过拖放式界面和内置模板即可完成应用定制与部署。压缩包共697个文件,约10.74MB…

2026/10/19 0:04:56

基于.NET9的多租户权限系统:数据权限与动态API落地实践

简介:这份资源是一套面向 .NET 与 Vue 全栈开发者的中台权限管理系统,后端基于 .Net9,前端采用 Vue3 Element Plus,并配套 uniapp uviewui 移动端方案,实现前后端分离。系统覆盖多租户隔离、数据权限、动态 Api、任务…

2026/10/19 0:04:56

场地预约小程序毕设实战:SSM+微信小程序+MySQL数据库设计到避坑

简介:面向毕业设计场景的场地预约小程序完整项目,基于微信小程序SSMMySql技术栈开发,适合计算机相关专业学生作为选题参考、功能扩展或二次开发起点。系统实现场地类型管理、场地管理、预约管理、取消申请与押金退回等功能,分为管…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑