在 2048 里能够得到的最大的数是多少?

Michael Brand 在 Using your Head is Permitted 趣题站 2014 年 4 月的谜题中提出了一个这样的问题:在最近非常流行的小游戏 2048 中,你能得到的最大的数是多少?

在这里,我们简单描述一下游戏的规则。游戏在一个 4 × 4 的棋盘上进行,棋盘里填有一个个的“数块”,每个数块上都写有某个形如 2n 的正整数。每一步,你需要从上、下、左、右四个方向中选取一个方向,按下对应的方向键之后,所有的数块都会“落”到这个方向;若有两个同种的数块在此过程中发生碰撞,则它们的值会相加起来,并合成一个新的数块。然后,系统会在棋盘中随机选择一个空白位置,并在此生出一个新的数块,上面写有数字 2 或者数字 4 (两种情况之比为 9 : 1)。游戏开始时,棋盘上会自动生成两个随机的数块,你的目标就是通过有限步的操作,得出一个写有 2048 的数块。当然,即使得到了 2048 这个数块,游戏也不会自动结束,你还可以向更大的数发起挑战。于是就有了我们刚才的问题:理论上,这个游戏当中能够得到的最大的数是多少?

可以证明,我们永远不可能在 2048 当中玩出 218 这个数。

让我们把棋盘上的所有数全部加起来,并在累加过程中不断关注当前总和的二进制表达。如果棋盘里的数分别是 2, 4, 16, 64, 16, 2 的话,累加结果的二进制表达依次为 10 → 110 → 10110 → 1010110 → 1100110 → 1101000 。你会发现,由于棋盘上的每个数都是形如 2n 的正整数,因而把它加进总和之后,这个总和的二进制表达里最多只会多出一个数字 1 (如果发生了进位,数字 1 的个数可能会不变甚至减少)。这意味着,如果最终棋盘上的所有数之和的二进制表达当中一共有 k 个数字 1 ,那就说明刚才至少有 k 个数在相加,换句话说棋盘里至少有 k 个数块。

容易看出,每走一步之后,棋盘上的所有数之和都会增加 2 或者 4 。如果最终棋盘上出现了一个 218 ,就说明棋盘上的所有数之和至少是 218 ,那么在此之前棋盘上的所有数之和一定经历过 218 – 2 或者 218 – 4 。前者的二进制表达为 11 1111 1111 1111 1110 ,这里面有 17 个数字 1 ,超过了棋盘里总的格子数,因而显然是不可能的。后者的二进制表达是 11 1111 1111 1111 1100 ,这里面有 16 个数字 1 ,正好是棋盘里总的格子数。这说明,此时棋盘刚好被填满, 22, 23, 24, …, 217 这 16 种不同的数块各有一个。这意味着棋盘里不但没有空白的格子,也没有相同种类的数块可以合并,此时玩家直接就死掉了!因而,我们是没有办法得到 218的。

因此, 217 = 131072 成为了 2048 这个游戏中数块大小的一个理论上限。但是,我们真的能弄出 131072 吗?看上去,我们好像只需要构造出下图所示的局面就行了,但这个局面本身能否实现,还有待进一步讨论。 Michael Brand 猜测,理论上 131072 也是无法得到的,但他不能证明这一点。我虽然在网上看见过很多网友宣称自己打出过 131072 ,甚至有的网友发出了最后几步的视频(比如这里),但由于我从来没有看到过完整的演示过程,因而也持怀疑态度。期待万能的网友们能够提供一种简洁有效的构造解,来说明当运气足够好的情况下,我们有办法打出 131072 ;或者找到一个更好的证明方法,足以说明 131072 也是理论上不可能实现的。

在 2048 里能够得到的最大的数是多少?

时间: 2024-10-19 19:03:51

在 2048 里能够得到的最大的数是多少?的相关文章

VS里统计整个解决方案代码行数的方法

VS里统计整个解决方案代码行数,在查找里输入正则表达式:b*[^:b#/]+.*$.如下图所示: 结果如下图所示:

Python数据科学手册Seaborn马拉松可视化里时分秒转化为秒数的问题

Python数据科学手册Seaborn马拉松可视化里时分秒转化为秒数的问题 问题描述: 我实在是太懒了,问题描述抄的网上的哈哈哈:https://www.jianshu.com/p/6ab7afa059d1 在做Python Data Science Handbook的实例学习,4.16.3 案例:探索马拉松比赛成绩里,有提示将时分秒的时间化为秒的总数,以方便画图.书里给出的指令是: data['split_sec']=data['split'].astype(int)/1E9 data['fi

WebContent的子目录里面的jsp文件无法将数据传递给Servlet

在WebContent下创建子目录FormCheck,register.jsp将跳转到RegisterServlet这个Servlet中去 分两种情况:在web.xml里面配置 和 使用注解 1.在web.xml里面配置 https://blog.csdn.net/cktmyh/article/details/47354869 在<url-pattern>标签中,加上子目录 2.使用注解 https://www.bbsmax.com/A/ZOJPODvezv/ 即在Servlet类的注解里面把

SQL 用户定义表类型,在存储过程里使用数据类型作參数

在数据库编程里使用数据类型,能够提高代码的重用性.它们常常被使用在方法和存储过程中.使用数据类型,我们能够避免在存储过程里定义一串的參数,让人眼花缭乱,它就相当于面向对象语言里.向一个方法里传入一个对象,而该对象有各种属性,存储过程仅仅须要获取这个对象就能获取到各个參数,然后做出对应的处理.有所不同的是SQL的表类型是能够包括多条数据的.到底是怎么一回事,且看以下的样例. 1. 首先我创建了一个学生表,包括四个字段,主键是从1開始的自增长型. GO CREATE TABLE STUDENT( I

HDU-3579-Hello Kiki (利用拓展欧几里得求同余方程组)

设 ans 为满足前 n - 1个同余方程的解,lcm是前n - 1个同余方程模的最小公倍数,求前n个同余方程组的解的过程如下: ①设lcm * x + ans为前n个同余方程组的解,lcm * x + ans一定能满足前n - 1个同余方程: ②第 n 个同余方程可以转化为a[n] * y + b; 合并①②得:lcm * x + ans = a[n] * y + b; => lcm * x - a[n] * y = b - ans(可以用拓展欧几里得求解x和y) 但是拓展欧几里得要求取余的数

程序里的国际时区和夏令时

UTC和GMT到底是什么 gmt和utc都是标准时间. GMT是比较古老的时间较量标准,根据地球公转自转计算时间.UTC则是根据原子钟来计算时间,现在基本都用UTC时间.时区的设置之前研究过https://java-er.com/blog/php-utc-time-default-set/,本文主要研究夏令时 夏令时计算有几个坑,需注意: 1) 时间服务器返回的时间为1900距今的秒数,而我们需要借助unix时间函数转为可读的时间 ,因此需要先把这个时间减去70年(2208988800s). 2

跨越千年的RSA算法

跨越千年的RSA算法 数论,数学中的皇冠,最纯粹的数学.早在古希腊时代,人们就开始痴迷地研究数字,沉浸于这个几乎没有任何实用价值的思维游戏中.直到计算机诞生之后,几千年来的数论研究成果突然有了实际的应用,这个过程可以说是最为激动人心的数学话题之一.最近我在<程序员>杂志上连载了<跨越千年的 RSA 算法>,但受篇幅限制,只有一万字左右的内容.其实,从数论到 RSA 算法,里面的数学之美哪里是一万字能扯完的?在写作的过程中,我查了很多资料,找到了很多漂亮的例子,也积累了很多个人的思考

Amoeba for MySQL

Amoeba for MySQL 2014年2月4日 | 标签: 来源:http://docs.hexnova.com/amoeba/ Amoeba for MySQL致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当query 路由功能,专注 分布式数据库 proxy 开发.座落与Client.DB Server(s)之间.对客户端透明.具有负载均衡.高可用性.Query过滤.读写分离.可路由相关的query到目标数据库.可并发请求多台数据库合并结果. 在Amoe

vc++HOOK详细讲解

消息钩子函数入门 Windows 系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是 Windows 系统中非常重要的系统接口,用它可以截获并处理送给其他应用程序的消息,来完成普通应用程序难以实现的功能.钩子可以监视系统或进程中的各种事件消息,截获发往目标窗口的消息并进行处理.这样,我们就可以在系统中安装自定义的钩子,监视系统中特定事件的发生,完成特定的功能,比如截获键盘.鼠标的输入,屏幕取词,日志监视等等.可见,利用钩子可以实现许多特殊而有用的功能.因此,对