您的位置:首页 > 其它

约瑟夫问题的另类思维

2009-11-06 18:58 190 查看
  先说一个高斯的故事:

  高斯10岁时,小学老师出了一道算术难题: “ 算出从1 到 100 中所有整数的和”。当时除了高斯之外的所有学生都开始从1到100的加,但是高斯确是先分析了下求和的规律 : 1 + 100 = 2 + 99 = 3 + 98 = …… = 50 + 51 = 101 ,在算出这样的组合有多少个, 很简单就得出了答案是: 101×50 = 5050 。

  说到约瑟夫问题,我向大家都是非常熟悉的,如果让大家为这个问题编个程序,普遍想到是使用循环链表或者二维数组来解决。 这是有一次我在百度知道上看到的,当时时间不多,所以就没认真分析,今天又碰到了,就拿出来了。代码如下:

#include<stdio.h>
2
3void main()
4

  运行结果:

  

  

 

  我想用链表实现这个问题,光一个链表的代码量就完全达到这个水平了,在空间复杂度上也就不用比了。当然你完全是为了联系学习C++ 和链表就不推荐了。之所以拿出来就是为了让大家感受下数学在程序开发中的地位。

  这个算法主要部分是一个迭代的过程——在第二个循环体内,所以就不说当 t < nPerson的情况了,我们将算法分成两个部分:

  1. 求 t ,i * nStep, 从表达式的意思上来讲,它就是为了表示重复计数的情况下,到第 i 跳的人,总共数了多少人。

  2. 迭代——化简 t 使其有意义。每次循环使得问题的规模减小,当 t 的正常时算法结束。

  正如我以前写过的那篇随笔所说迭代使得程序不易看懂。不过很显然的可以看到主要是靠不断 t - nPerson 来使得 t 的值小于nPerson。不过比较难理解的是后面的那部分,(t-nPerson-1) / (nStep-1),它是这个算法中比较重要的一个因子,它的意义是算出到t - nPerson前总过跳过多少人。每减少nPerson次就要加上跳掉的人,这样就保持了t所指向的人的恒定,可以算一下(t-nPerson-1) / (nStep-1)的值是恒小于 nPerson的,所以t不断减少指到它有意义。

  其实这个算法写起来简单,但是其时间复杂度还是比较高的。因为当 i 很大的时候 (t-nPerson-1) / (nStep-1)的值是很接近nPerson的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: