【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;
}

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

相关推荐
EricWang13589 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??11 分钟前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
希言JY1 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若1 小时前
C语言比较两个字符串是否相同
c语言
TeYiToKu3 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
互联网打工人no13 小时前
每日一题——第一百二十四题
c语言
爱吃生蚝的于勒3 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法
羊小猪~~3 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
洋2403 小时前
C语言常用标准库函数
c语言·开发语言
徐嵌4 小时前
STM32项目---畜牧定位器
c语言·stm32·单片机·物联网·iot