约瑟夫(Josephus)问题
来源:互联网 发布:nba英雄网络链接 编辑:程序博客网 时间:2024/06/13 20:28
一群小孩围成一圈,任意假定一个数n,从第一个小孩起,顺时针方向数,每数到第m个小孩时,该小孩便离开。小孩不断离开,圈子不断缩小。最后剩下的一个小孩便是胜者。求胜者的编号?
/************************************ // 函数名称: josephus // 作 成 者:Erick.Wang // 作成日期:2016/07/19 // 返 回 值: void // 参 数: m,n // 函数说明:用于解决约瑟夫问题 1.对于1……N的数据,声明一个2N的数组; 2.定义两个指针cur和tail,分别用于标记当前访问的数据和最后一个数据; 3.每访问过一个都将其放置到数组最后位置,当cur的访问次数是M的倍数时, 将该位置的数据标记为剔除状态; 4.当tail指针满的时候将剩余数字前移,继续第3步操作。//************************************/#define M 2#define N 8int a[N*2 + 1];void josephus(int m,int n){ int step = 0; int count = 0; int cur = 1; int tail = n; for (int i=1; i<=n; i++){ a[i] = i; } while (1){ for (int i=1; i<=n+n; i++){ printf("%d ",a[i]); } printf("\n"); if (step == m){ printf("delete %d\n",a[cur]); a[cur] = -1; cur ++; count ++; step = 0; } if (count == n-1){ printf("The last one=%d\n",a[cur]); break; } a[tail + 1] = a[cur]; //a[cur] = 0; cur ++; tail ++; step ++; if (tail == n*2+1){ //执行移动 int j=1; for (int i=cur-1; i<tail; i++){ a[j ++] = a[i]; } cur = 1; tail = j; } } return;}
以上方法虽然能解决问题,但是当n和m在成百上千的时候时间消耗也是很大的,所以对此问题先用数学模型进行分析,然后再求解,以下有个更快速的方法,时间复杂度为O(N)。
令f表示i个人玩游戏报m退出最后胜利者的编号,最后的结果自然是f[n]
递推公式
f[1]=0;
f[i]=(f[i-1]+m) mod i; (i>1)
有了这个公式,我们要做的就是从1-n顺序算出f的数值,最后结果是f[n]。因为实际生活中编号总是从1开始,我们输出f[n]+1
由于是逐级递推,不需要保存每个f,程序如下:
#include <iostream>using namespace std;const int m = 3;int main(){ int n, f = 0; cin >> n; if(n<=0) { cout << 0 << endl; return 0; } for (int i = 1; i <= n; i++) f = (f + m) % i; cout << f + 1 << endl; return 0;}
参考的资料:
http://blog.csdn.net/firetoucher/article/details/632838
http://www.cnblogs.com/heqinghui/archive/2012/10/04/2711709.html
http://baike.baidu.com/link?url=vwVPN8BkKiW3aJ7UDI31OuAY6bA0YmxVP5tFKs9j_iUMKxjloEi_Jh4s9Rcl3ubkst99ZAuJkgX6xMMyNm7o8a
很精彩:
http://www.cnblogs.com/void/archive/2011/04/21/2024377.html
1 0
- 约瑟夫(Josephus)问题
- 约瑟夫(Josephus)问题
- 约瑟夫(Josephus)问题
- Josephus问题(约瑟夫环)
- Josephus(约瑟夫环)问题
- Josephus(约瑟夫斯)问题
- 约瑟夫问题(Josephus problem)
- 约瑟夫问题(Josephus Problem)
- 约瑟夫问题(Josephus problem)
- 约瑟夫(Josephus)问题的实现
- 约瑟夫环问题(josephus problem)详解
- Algorithm Gossip: 约瑟夫问题(Josephus Problem)
- 约瑟夫(Josephus problem)环问题初探
- Java-约瑟夫问题(Josephus Problem)
- 关于约瑟夫问题(Josephus Problem)
- 约瑟夫问题(Josephus)链表实现
- Josephus约瑟夫环问题
- 约瑟夫环问题(Josephus)
- 函数
- 100. Same Tree
- crontab+shell 作业流程调度
- 虚拟机 可以多个wifi地址 登录【还得改hosts 与 ifcfg-eth0】
- 百度地图sdk使用(2) 定位
- 约瑟夫(Josephus)问题
- 移动端各终端的适配问题研究--关于viewport
- Hadoop 2.x源码包编译
- 设计模式之策略模式
- 我的C++回调函数的理解
- 记录输入三数排序,字符串操作
- Android studio启动到指定Activity
- 集合映射
- Git学习(一)