7-7 约瑟夫环

作者 吴锦桥

单位 西北农林科技大学

有N个人围成一圈(编号为1~N),从第1号开始进行1、2、3报数,凡报3者就退出,下一个人又从1开始报数……直到最后只剩下一个人时为止。请问此人原来的编号是多少?

输入格式:

在一行中给出1个不超过100的正整数N。

输出格式:

在一行中输出最后剩下那个人的编号。

输入样例:

10

输出样例:

4

代码长度限制                        16 KB

时间限制                                400 ms

内存限制                                64MB

 该题可以模拟报数过程的行为逻辑,来编写代码。

例如下面的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
    int i, j, n, count = 1, a[1000] = { 0 };
    scanf("%d",&n);
    i =j= 0;
    while ((j++) < n) {
        while (1) {
            i++;
            if (i > n) i = 1;
            while (a[i] != 0) {
                i++;
                if (i > n) i = 1;
            }if (count == 3) {
                a[i] = 1;
                count = 1;
                break;
            }
            count++;
        }
    }
    printf("%d", i);
    return 0;
}

 但也可以使用数学知识来解决,是有关模的运算的知识

这类题还被称为约瑟夫环问题

设 n 个人的问题的解为 f(n),即 n 个人中最后一个被移除的人的编号。我们可以得到递推关系:

f(n)=(f(n−1)+m) mod n

其中,m 是数的步长,表示每次数多少个人。这个递推关系的意义是,如果我们知道 n-1 个人的问题的解 f(n-1),那么在 n 个人的情况下,就是在 n-1 个人的基础上再数 m 个人,并且取余数(因为是环形)。

初始情况是 f(1) = 0,因为只有一个人的时候,他就是最后一个被移除的人。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
    int n, s = 0, i;
    scanf("%d", &n);
    for (i = 2; i <= n; i++)
        s = (s + 3) % i;
    printf("%d", s + 1);
    return 0;
}

直接循环迭代,求出来的结果再+1。因为是在从0开始的环计算的,而题目的序号是从1开始的

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值