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

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

相关推荐
No0d1es4 小时前
电子学会青少年软件编程(C/C++)5级等级考试真题试卷(2024年6月)
c语言·c++·算法·青少年编程·电子学会·五级
Peter_Deng.8 小时前
Linux 下基于 TCP 的 C 语言客户端/服务器通信详解(三个示例逐步进阶)
服务器·c语言·网络
John.Lewis11 小时前
数据结构初阶(13)排序算法-选择排序(选择排序、堆排序)(动图演示)
c语言·数据结构·排序算法
丑小鸭是白天鹅14 小时前
嵌入式C语言学习笔记之枚举、联合体
c语言·笔记·学习
GUET_一路向前14 小时前
【C语言防御性编程】if条件常量在前,变量在后
c语言·开发语言·if-else·防御性编程
pusue_the_sun15 小时前
数据结构——栈和队列oj练习
c语言·数据结构·算法··队列
Dontla16 小时前
Makefile介绍(Makefile教程)(C/C++编译构建、自动化构建工具)
c语言·c++·自动化
奶黄小甜包16 小时前
C语言零基础第18讲:自定义类型—结构体
c语言·数据结构·笔记·学习
一支闲人16 小时前
C语言相关简单数据结构:双向链表
c语言·数据结构·链表·基础知识·适用于新手小白
John.Lewis17 小时前
数据结构初阶(19)外排序·文件归并排序的实现
c语言·数据结构·排序算法