约瑟夫问题直接求取结果的思路

    xiaoxiao2025-04-15  11

    本人比较笨,约瑟夫问题的求解方法想了好久才想通,在这里留一篇文章,记录一下。

    约瑟夫问题:n个人,数m,列出顺序。

    1,用算法模拟数数过程,通过一个一个的排除,最后得到最终的结果:

    首先解决思路问题,每次数数m个,一共数n次,所以一共经过n*m次,然后定义一个int t,用来算作每个人报数的时候报出的数,

    然后没报一下,判断所在的是否还存在,只有两个问题,一个是是否到了末尾,如果到了末尾就转到前面去;然后判断是否已经数出,如果数出,直到

    没有数出的数为止做while循环。每次做完一个m,就要归零(输出一个被数出的人),因为是从零开始的,所以输出的人要加上1.

    for(int i=0;i<n;i++){             for(int i0=0;i0<m;i0++){//此为一共计算的n*m次                 t++;//报数                 if(t==n) t=0;                 while(monkey[t]==0){                     t++;                     if(t==n) t=0;                 }             }         //    cout<<t+1<<endl;             monkey[t]=0;             if(i==n-1) cout<<t+1<<endl;;         }

    上述的算法s

    2.用递推的方法求解:

    因为直接要求的最后的一个人用以下形式来表示:

    0 1 2 3 4 5 。。。。。 n-1,

    在排除第一个人的时候,当n》m时,排除的是第m个,(代号为m-1),当n》m时,第n-m个,排除的是(n-m-1),所以排除的是第m mod n个

    再将所有的重新排列一下为

    m m+1  m+2 m+3 。。。。n-1 0 1 2 3 。。 m-2,,将其看作从

    0  1  2 3 4 。。。。。 n-2,根据前面的算式,转换成n-1个人的约瑟夫问题,如果知道是第x个人是n-1个人约瑟夫问题的最后的人,根据以上的表,就能够知道第n人的约瑟夫问题最后一个人是谁

    所以关键就是求出递推关系,怎么从n-1人的约瑟夫问题的解转换到n人约瑟夫问题的解:

    n-1个人约瑟夫问题(x)的第二重排除根据n人约瑟夫问题(x‘)来推导,x'=(x+m) mod n

    (如果第0是最后胜利者,则m mod n=m为最后胜利者)

    以后就是根据递推关系,根据1人约瑟夫问题的解为它本身,求出n人约瑟夫问题的解

    #include <iostream> using namespace std; int main() {     int n,m;     while(1){         cin>>n>>m;         if(n==0&&m==0) return 0;         int k=0;         for(int i=1;i<=n;i++){             k=(k+m)%i;         }         cout<<k+1<<endl;//计算从0开始,实际从1开始     } }

    转载请注明原文地址: https://ju.6miu.com/read-1298079.html
    最新回复(0)