约瑟夫问题

经典的Joseph问题吧,说有n个要被处决的人(编号0~(n-1)),从0开始报数,报到(m-1)的会被杀掉,剩下的人继续从0开始报数,如此下去最后剩的一个人会存活下来

: 很明显剩下未处死的人编号为0

我们来研究一下相邻两次的操作:

x: 0 1 2 3 4 5 …… m-2 m-1 m m+1 …… n-1 n人
y:               n-2 删除 0 1     n-1人

 

 

 

对比这两次操作发现 同一人的序号 之间的关系:x=(y+m)%n

因此可以从后往前递推:

       存活人序号:(最后一次)     :t=0

                         (倒数第二次)  :t=(t+m)%2 (有2人)

         (倒数第三次):t=(t+m)%3  (有3人)

 

因此:

      核心算法: int ans=0;//存活人最后的序号为0

 for(int i=2;i<=n;i++)

       ans=(ans+m)%i;

 

PS:只有最后一个人的遍历是可以从0开始构建的,在这个人的编号向上有每次的相对编号,一直推到到第一次,才是绝对编号。而相对编号之间的转变遵循上述公式。

 

参考:http://www.cnblogs.com/wuzhibin/archive/2012/02/17/2355952.html

posted on 2012-08-21 18:18  gcpopo  阅读(146)  评论(0)    收藏  举报

导航