约瑟夫环问题
2016-07-11 21:48
281 查看
约瑟夫环(约瑟夫问题):已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号k的人开始报数,数到m的那个人出列;他的下一人又从1开始报数,数到m的那个人出列;依此规律重复下去,直到周围的人全部出列,最后出列人的编号是多少?(摘自百度百科)
对于这个问题,网上有很多版本的实现,包括链表、数组等,但是个人觉得实现都有点繁琐,以下是我个人的实现:
当然,以上都属于暴力求解,算法的时间复杂度高达O(mn)。在网上对该问题的搜索,我发现有个更快捷的方法,是利用数学分析,得出问题的递归式:
f(1) = 1;
f(i) = (f(i -1) + m) % m; i > 1
注:f(i)表示i个人玩游戏报m退出最后胜利者的编号
如此,问题的时间复杂度为O(n)。
具体的推导分析可参考
http://blog.163.com/soonhuisky@126/blog/static/157591739201321341221179/
对于这个问题,网上有很多版本的实现,包括链表、数组等,但是个人觉得实现都有点繁琐,以下是我个人的实现:
#include <iostream> #define N 300 //总人数n #define M 5 //报数的最大值m #define K 1 //报数的起始编号k /********************************************* **本质上是利用环形双向链表解决joseph问题,不过 **此处的链表是利用数组prev 及next 实现 *************************************/ int main() { int prev ,next ; for (int i=0; i<N; ++i) { prev[i] = (i + N - 1) % N; next[i] = (i + 1) % N; } int j = K - 1; for (int k=1; j!=next[j]; j=next[j], k=(k+1)%M) { if (k == 0) { prev[next[j]] = prev[j]; next[prev[j]] = next[j]; } } std::cout << "The last number is " << j+1 << "!\n"; return 0; }
当然,以上都属于暴力求解,算法的时间复杂度高达O(mn)。在网上对该问题的搜索,我发现有个更快捷的方法,是利用数学分析,得出问题的递归式:
f(1) = 1;
f(i) = (f(i -1) + m) % m; i > 1
注:f(i)表示i个人玩游戏报m退出最后胜利者的编号
如此,问题的时间复杂度为O(n)。
具体的推导分析可参考
http://blog.163.com/soonhuisky@126/blog/static/157591739201321341221179/
相关文章推荐
- 深入理解约瑟夫环的数学优化方法
- 批处理解约瑟夫环应用题代码
- java 实现约瑟夫环的实例代码
- php解决约瑟夫环示例
- 详解约瑟夫环问题及其相关的C语言算法实现
- C++循环链表之约瑟夫环的实现方法
- 约瑟夫环问题(数组法)c语言实现
- python超简单解决约瑟夫环问题
- Python实现约瑟夫环问题的方法
- Python实现约瑟夫环问题的方法
- 【OJ日志】超级约瑟夫
- 约瑟夫自杀环
- 简单约瑟夫环 系列(1)【简单一维数组】
- 约瑟夫环
- 数据结构复习(重写某些重要数据结构API) ------------约瑟夫环
- 约瑟夫环数学解法
- 循环链表实现Joseph环(约瑟夫环)猴子选大王类似问题
- poj 1012 约瑟夫置换
- poj 2244 约瑟夫环
- xcode-C语言出接触_约瑟夫环_循环链表