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

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

约瑟夫问题: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开始
    }
}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值