约瑟夫(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