|
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用 · 内置多项VBA编程加强工具 ★ 免费下载 ★ ★ 使用手册★
国王招了2010个囚犯,对他们说:你们犯的是死罪,本应该将你们统统杀掉,但我慈悲为怀,给你们一次求生的机会。你们以1.2.3.4..2010围成一圆圏,从1号开始我隔1人杀1人即依次杀死1.3.5.7.9....2009,至到这个圆圈缩小到只剩一个,我将开恩将这位犯人释放。。请问最后释放的是几号呢??
(这个问题是在其它地方转的,原题是100个犯人,我把它放大了,为的是避免一些人暴力解题,方法思路才是最重要的,请用EXCEL相关功能解答,不要使用Vb,编程等)
82楼我给的答案,仍期高手如现。
胡剑的精彩表述,初读此题的可以拜读一下
============================================================================
要说明这个问题,要先抓住两点:
第一:当总人数为2的整数次方(就是,1,2,4,8...)的时候,幸存者就是这个数。
论证:
造两个概念,(当然也不是我造的,前面已经有仁兄说到了),纵队杀,绕圈杀。
如果纵队杀,这个简单,前面一大片1024的答案就可以看出大家很熟悉,呵呵。
纵队杀:
当总人数正好为2的N次方时, 对于纵队杀,第一轮最后一人是幸存的,并且剩余的人数为2的(N-1)次,就是说第二轮时的人数依然是2的整数次方。于是,第二轮最后一人依然是幸存的...如此循环下去,最后一个人就成为了最后的幸存者。
绕圈杀
当总人数正好为2的N次方时,绕圈杀和纵队杀是如出一辙的。因为第一圈以后最后一个是幸存的,按照隔一个杀的规则,最后一个人成为了那个 间隔 ,于是第二圈开始的时候又是从头开始间隔杀,由于此时总人数为2的N-1次,于是最后一个人又是幸存者,又作为间隔,下一轮又是从头开始间隔杀。如是,如同纵队杀一样,最后一个人是幸运者。
我们换个表述,当总人数为2的N次方时,幸运者就是起始者背后的那个人...
如果以上明白了,我们只要再换个表述你就应该明白了:
当剩余人数为2的N次方时,幸运者就是即将被杀的那个人的背后那一个。
这样,我们只要关心当前人数下需要送走几个(比如说是n个)才能得到2的N次方,我们就知道即将被送走的那个人的序号为 n*2-1+2 (n*2-1,表示奇数,其中+2表示又要间隔一个人),那么幸运数 就是 这个人的背后,于是就是 (n*2-1+2)-1=n*2.
于是对于2010,就是 (2010-1024)*2=1972。
=============================================================================================
这个题,是个好题。只是楼主表述的时候没有 把第二圈的意图表明确,我们知道你语言上是明白了,但用数字的时候 缺了 第一圈 和 第二圈 过渡的成分,呵呵。
习惯性的思路都是往前的,这个有点递归的味道...
==========================================================================================
呵呵,回头看这个题,我觉得就是比较注重推导,替代,打破一些惯性。
比如,我第一次看的时候是割裂着来分析的,就是一圈一圈来,而实际上他是一个圆,所谓的一圈接一圈是人为的思想,其实他是一个螺旋式渐进的,无所谓头也无所谓尾,是周而复始,循环往复的。
无所谓头,无所谓尾,因此处处可以看成是头,处处可以看成是尾.....跑到太极去了,呵呵
如果把 整2的N次 绕圈杀 看成是一个封装的机制(比如某函数),确定了第一个位置,就绝定了最后最后的幸存者,那么我们只要去找到那个 输入量(即第一个位置就行了,当然是里处理过了。)
==========================================================================================
78楼的cbtaja 给了我们这样一个算法。
首先,这的确是一个递归问题,需要用到归纳假设,这在我前面的附件中是已经说过的。
-----------------------------------------------------------------------------------------------------------------------
我的公式是:=IF(LOG(A1,2)=INT(LOG(A1,2)),A1,2*A1-2^(INT(LOG(A1,2))+1))
含义是:①、当总人数A1恰好是2^K(即2的K次方,K为整数,且满足2^K>=1)时,这时的最后一个人成为幸运者,即:幸运号=2^K。
②、当总人数A1处于2^K与2^(K+1)之间时,如果结论①是成立的,则当KILL了A1-2^K个人后,剩余了2^K人,这时的第2^K号是幸运者,他的最初序号必定是已经被KILL的人数的2倍,即:幸运号=2*(A1-2^K)。
-----------------------------------------------------------------------------------------------------------------------
证明:
由于结论①又是结论②的充分条件,只需证明结论①成立,则结论整体成立。
结论①的证明:
由于2^K=(2^K-1)+1
=(2^(K-1)+2^(K-2)+……+2^2+2+1)+1,
即经过第1次KILL(干掉了共计2^(K-1)人)、第2次……直到第K次KILL(干掉了共计2^(K-K)人,即1人),恰好剩余1人,最后这个人成为幸运者。同时也说明,KILL过程是经历了完整的K轮才结束。
反过来,
当经历K轮而只剩下这位幸运者时、最初的总人数应该就是第2^K人,
而且,如果每轮KILL过后重新从1开始编序号,且把幸运者的序号定为M,
那么幸运者在倒数第1轮KILL前的序号应该是M*2,
在倒数第2轮前的序号应该是(M*2)*2,即M*2^2,
……
在倒数第X轮的序号为M*2^X
又:已知经历K轮时只剩余了这1名幸运者,这时对剩余的1人从1开始重编序号,则幸运者的序号M这时只能等于1,
用数学语言来表达,即:当X=K时,M=1
代入幸运号的表达式M*2^X,即幸运号=1*2^K,简写为:
幸运号=2^K
至此,已证明结论①是正确的。
证明完毕。
-----------------------------------------------------------------------------------------------------------------------
接下来,只需把结论整体用公式表达出来。
把结论①的假设条件:A1=2^K(K为整数)代入上式得到:幸运号=2^LOG(A1,2),即:
幸运号=A1 (结论①的公式)
由结论①的假设条件A1=2^K(K为整数),可得K=LOG(A1,2),且INT(K)=K,用公式表达该假设条件,即
LOG(A1,2)=INT(LOG(A1,2)) (条件表达式的公式)
当不符合条件1时,即当总人数A1处于2^K与2^(K+1)之间时,假设先按规则干掉一部分人,使得剩余的人恰好可以经历K个完整轮次的KILL而只剩余幸运者、且K为最大的可能值,这时
K=int(LOG(A1,2))
把它代入结论②:幸运号=2*(A1-2^K)得到:
幸运号=2*A1-2^(int(LOG(A1,2)+1) (结论②公式②)
用if函数来综合条件表达式、结论①、结论② 的三个公式,得到最终公式如开篇所述。
[ 本帖最后由 lovezhangfu 于 2010-7-9 16:50 编辑 ] |
评分
-
1
查看全部评分
-
|