ACM复习(3)1139 约瑟夫环问题

Description
约瑟夫(josephus)环是这样的:假设有n个小孩围坐成一个圆圈,并从1开始依次给每个小孩编上号码。老师指定从第s位小孩起从1开始报数,
当数到m时,对应的小孩出列,依次重复,问最后留下的小孩是第几个小孩?例如:总共有6个小孩,围成一圈,从第一个小孩开始,
每次数2个小孩,则游戏情况如下:
小孩序号:1,2,3,4,5,6
离开小孩序号依次为:2,4,6,3,1
最后获胜小孩序号:5

输入格式
每组输入是三个整数n,s,m。(1 <= n <= 30, 1 <= s <= n,1 <= m <= 10) ;

输出格式
对于每组输入,请输出最后留下小孩的序号。

输入样例
6 1 2

输出样例
5


解题思路

因为 n, s, m都很小所以直接模拟就行了

#include<stdio.h>
int main ()
{
    int n, s, m, i, k, d = 0, l;
    scanf("%d%d%d", &n, &s, &m);
    int kids[40] = {0};
    // 初始小孩的位置减一 
    l = s - 2;
    for(i = 0; i < 40; i++)
         kids[i] = i + 1;
    for(i = 0; i < n; i++)
    {
        // 只剩下一个小孩 
        if(i == n - 1)
            break;
        // (从初始小孩位置或上一个出列小孩位置)的下一个位置开始
        // 直到找到下一个出列小孩 
        for(k = l + 1; ; k++)
        {   
            if(k >= n)
                k -= n;
            // 该小孩没有出列 
            if(kids[k] != 0)
                d++;
            if(d == m)
                break; 
        }
        // 标志该小孩出列 
        kids[k] = 0;
        // 上一个出列小孩的位置  
        l = k;
        d = 0;
    }
    for(i = 0; ; i++)
        if(kids[i] != 0)
            break;
    printf("%d", kids[i]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值