码迷,mamicode.com
首页 > 其他好文 > 详细

剑指offer (45) 约瑟夫环问题

时间:2014-06-28 10:01:14      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   width   问题      

题目:有编号从 1 到 n 的 n 个人坐成一圈报数,报到 m 的人出局,下一位再从 1 开始, 如此持续,直止剩下一位为止,报告此人的编号 X。输入 n, m,求出 X

题解分析:

一开始有 n 个人,报到 m 的人出局后,如果我们从刚才出局的那人的下一位开始重新从 1 开始编号,原问题就转化为了一个 n – 1 人的问题。

如下表所示:

原始编号 第一人出局后的编号
m + 1 1
m + 2 2
m + 3 3
... ...
m - 2 n - 2
m - 1 n - 1
m 已出局

老的编号 i 与新编号 j 之间的关系为:i = (j + m) % n ,其中“%”为取余数运算。

显然,这个过程可以不断重复,n – 1 规模的问题可以继续转化为 n – 2 规模的问题、n – 3 规模的问题,直到最后只剩下一个人。

我们可以总结出如下递推公式:

 

f(n) = (f(n – 1) + m) % n, (n > 1),其中 f(n) 为当场上还有 n 个人时某个在场的人的编号

当最后只剩下一个人时,这个人的编号显然只能是 1 ,即 f(1) = 1,这时,我们可以根据上面的公式反推回去,推导出当 n 个人都在场时他的编号。

int LastNumber(int n, int m) 
{
    assert(n > 0 && m > 0);
    int last = 0;
    for (int i = 2; i <= n; ++i) {
        last = (last + m) % i;
    }
    return last + 1;
}

 

剑指offer (45) 约瑟夫环问题,布布扣,bubuko.com

剑指offer (45) 约瑟夫环问题

标签:style   blog   color   width   问题      

原文地址:http://www.cnblogs.com/wwwjieo0/p/3810965.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!