【C语言】转圈报数问题(三种方法--指针,数组)

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

方法一:

cpp 复制代码
#include <stdio.h>
#define N 10

int main()
{
    int a[N];    // 用数组保存参与报数的人员编号
    int i, j, m, out, count;

    // 初始化编号,从1开始连续编号
    for (i = 0; i < N; i++) {
        a[i] = i + 1;
    }

    i = 0;    // i表示当前参与报数的人员在数组中的下标
    m = 3;    // 每次报数的个数
    out = 0;    // 记录已经退出报数的人数
    count = 0;    // 记录当前已经报数的次数

    // 当还有人参与报数时循环
    while (out < N) {
        // 如果这个人还没退出
        if (a[i] != 0) {
            count++;    // 增加报数次数
            // 如果报数次数达到了m
            if (count == m) {
                printf("%d ", a[i]);    // 输出该人员编号
                a[i] = 0;    // 标记该人员已经退出
                out++;    // 增加退出人数
                count = 0;    // 将报数次数清零
            }
        }
        i++;    // 指向下一个人员
        // 如果已经扫描完一圈,则重新开始
        if (i == N) {
            i = 0;
        }
    }

    return 0;
}

程序中,首先定义了一个长度为10的数组,用于保存参与报数的人员编号。然后初始化编号,从1开始连续编号。接着设定了3个变量:i表示当前参与报数的人员在数组中的下标,m表示每次报数的个数,out表示已经退出报数的人数,count表示当前已经报数的次数。

接下来,使用while循环来模拟报数的过程。首先判断当前参与报数的人员是否已经退出,如果还没退出,则增加报数次数count。如果报数次数达到了m,则输出该人员编号,标记该人员已经退出(将其编号置为0),增加退出人数out,并将报数次数count清零。接着将下标i指向下一个人员,如果已经扫描完一圈,则将下标重新指向第一个人员。最终,当所有人都退出报数时,程序结束。

方法二 (万能):

c 复制代码
#include <stdio.h>

int main()
{
    int n, m;
    printf("请输入参与游戏的人数:");
    scanf("%d", &n);
    printf("请输入报数的上限:");
    scanf("%d", &m);
    int a[n];
    for(int i = 0; i < n; i++)
    {
        a[i] = i + 1;
    }
    int k = 0;
    while(n > 0)
    {
        k += m - 1;
        if(k >= n)
        {
            k %= n;
        }
        printf("%d ", a[k]);
        for(int i = k; i < n - 1; i++)
        {
            a[i] = a[i + 1];
        }
        n--;
    }
    return 0;
}

运行该程序,按照提示输入参与游戏的人数和报数的上限,程序就会自动进行转圈报数,并输出出局人员的编号。

方法三(指针):

以下是C语言指针处理的代码实现:

c 复制代码
#include<stdio.h>
#include<stdlib.h>

int main()
{
    int n, k = 0, m = 3;
    printf("请输入参与游戏的人数:");
    scanf("%d", &n);
    int *a = (int*)malloc(n*sizeof(int)); // 动态分配内存空间
    for(int i = 0; i < n; i++)
    {
        *(a + i) = i + 1; // 初始化,编号从1开始
    }
    while(n > 1)
    {
        k = (k + m - 1) % n;
        for(int i = k + 1; i < n; i++)
        {
            *(a + i - 1) = *(a + i);
        }
        n--;
    }
    printf("最后留下的是编号为%d的人\n", *a);
    free(a); // 释放内存空间
    return 0;
}

首先使用动态分配内存空间,然后初始化参与者编号,随后通过指针实现转圈报数,最后输出留下的人员编号,并释放内存空间。

相关推荐
知南x41 分钟前
【Ascend C系列课程(高级)】(1) 算子调试+调优
c语言·开发语言
2的n次方_3 小时前
Runtime 执行提交机制:NPU 硬件队列的管理与任务原子化下发
c语言·开发语言
凡人叶枫3 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
凡人叶枫5 小时前
C++中输入、输出和文件操作详解(Linux实战版)| 从基础到项目落地,避坑指南
linux·服务器·c语言·开发语言·c++
傻乐u兔6 小时前
C语言进阶————指针3
c语言·开发语言
CodeSheep程序羊7 小时前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
I'mChloe7 小时前
PTO-ISA 深度解析:PyPTO 范式生成的底层指令集与 NPU 算子执行的硬件映射
c语言·开发语言
2的n次方_8 小时前
Runtime 内存管理深化:推理批处理下的内存复用与生命周期精细控制
c语言·网络·架构
嵌入小生0078 小时前
标准IO---核心函数接口延续(嵌入式Linux)
c语言·vscode·vim·嵌入式·小白·标准io·函数接口
历程里程碑9 小时前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法