约瑟夫环理解

问题描述:
. 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位?

网上的递推公式
f[1]=0;
f[i]=(f[i-1]+m)%i; (i>1)
我看了很长时间才看懂,所以把我的想法发出来。

比如说n为7,人分别为1 2 3 4 5 6 7

接下来为退出的过程
1204567    3退出 记为0
4567120    从4开始从新报数
4507120    6退出 记为0
7124500    从7开始从新报数
7104500    2退出  记为0
4571000   从4开始从新报数
4501000   7退出 记为0
1450000   从1开始从新报数
1400000   5退出 记为0
0400000   1退出  最后留下4

c代码实现如下

#include <stdio.h>
#include <stdlib.h>

int movethree(int a[],int n,int m)
{
    int b[n],i,j;

    if(a[2]==0)
        return a[1];
    else
    {
        for(i=0,j=0; j<n-m; i++,j++)
        {
            if(i==2)
            {
                a[i]=0;
            }
            b[j]=a[i+3];
        }

        b[n-3-m]=a[0];
        b[n-2-m]=a[1];
        b[n-1-m]=a[2];
        m++;
    }

    return movethree(b,n,m);
}

int main(void)
{
    int n,i,a[100];

    scanf("%d",&n);

    for(i=0; i<n; i++)
    {
        a[i]=i+1;
    }

    printf("%d\n",movethree(a,n,0));
    return 0;
}

比较简单的代码如下

#include <stdio.h>
#include <stdlib.h>

int threeout(int n)
{
    int i, r = 0;
    for (i = 2; i <= n; i++)
    {
        r = (r + 3) % i;
    }
    return r+1;
}

int main(void)
{
    int n;
    scanf("%d",&n);
    printf("%d\n",threeout(n));
    return 0;
}

这个问题我想的还不够,如果有更好的理解,希望讨论一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值