神庙逃亡的无限钻石

来源:互联网 发布:细说linux 李明 pdf 编辑:程序博客网 时间:2024/04/26 03:45

2014年8月,我基本上就是在神庙逃亡中度过的。

我截下了4种bug的图:


花了很久才知道这个任务到底是什么意思,miser是吝啬鬼的意思,就是说跑的时候不能碰到金币。

但是没有说细节,后来才知道,指的就是在矿洞里面不能碰到金币。

说实话,这个真的很难!

不过,我还是完成了,然而,完成了之后,就变成了:


真心无语MDZZ


据说这里叫云端,如果不小心触发了bug到了这里,就完全失去了对身体的掌控了。

刚开始的时候感觉很爽,什么都不用做,他会自己跑,没有障碍,距离一直在增加。

但是没过多久就之间挂了。。。


这运气。。。死的时候刚好钱币占了整个屏幕。

可以清晰的看到,钱居然是破的。。。

与此类似,我还收藏了一个钻石的图片:



好了,言归正传,本文的标题叫神庙逃亡的无限钻石。

在神庙逃亡已经没什么好玩的时候,我开始借助外挂看能冲到多远。

在网上下载的外挂,说是有无限钻石,但是其实也只有8亿多而已。

具体多少我忘了,不如就用图片里面的数字814778622

这么多钻石,最多能复活多少次呢?

(本文不考虑中途获得钻石)

第一次复活需要1个钻石,第二次需要2个,第三次需要4个。。。。。。

所以,复活n次一共需要2^n-1个钻石

2^29=536870912

所以,这么多钻石可以复活29次。

然后,这一局结束之后,就只剩下277907711个钻石了。

要多少局才能把钻石全部用完呢?

代码:

#include<iostream>using namespace std;int f(int n){cout << n << endl;int k = 1;while (k * 2 < n)k = k * 2 + 1;return n - k;}int main(){int n = 814778622;while (n)n = f(n);return 0;}


输出:

814778622
277907711
9472256
1083649
35074
2307
260
5
2
1

每运行一次n=f(n)刚好就是一局玩完了,f(n)就是剩下多少钻石。

如果用二进制表示的话:


显然,不断运行n=f(n)的话,n会严格单调递减,而且最后一定会变成0,于是循环结束。


现在,新的问题来了,对于任意的自然数n,运行多少次n=f(n)之后才会变成0呢?

我们用l[n]来表示答案,l是length的意思。

那么,根据f(n)的特点,可以得到关于l[n]的递推式,见代码。

代码:

#include<iostream>using namespace std;int l[100000];int f(int n){int k = 1;while (k * 2 < n)k = k * 2 + 1;return n - k;}int main(){l[0] = 0;for (int i = 1; i < 100000; i++)l[i] = l[f(i)]+1;return 0;}
结果很有意思:

l[100000]={0, 1, 2, 1, 2, 3, 2, 1, 2, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 3, 4, 3, 2, 3, 4, 3, 4, 5, 4, 3, ...}

随着i的增大,每次l要不就是增大1,要不就是减小1。

其实,这个只要用数学归纳法就可以证明。

但是不是对i进行归纳,而是对i的2进制的位数进行归纳,详情略。

如果不限于计算机,l是一个无限的数列,那么l将包含所有的正整数。

对于任意n,存在一个最小的m=2^n-n使得,l[m]=n





1 0
原创粉丝点击