报数游戏(C语言)

一、题目描述

给定一个圆圈,从圆圈中随机选定第一个人,并从他开始按顺时针方向进行报数,数到3的人退出圆圈,后面的人再接着从1开始报数,继续按顺时针方向数数,数到3的人退出圆圈……直到圆圈中只剩下一个人为止。问最后留下来的那个人是原来的第几号。

二、算法思路

1.先用动态内存分配申请一个大小为 n 的 int型数组circle来模拟原来的圈子,数组下标代表每个人的编号,如circle[0]表示1号的人。

2.用一个指针p 指向circle[0],表示从第一个人开始报数。

3.建立一个循环,当圈子中只剩下一个人时退出循环。在循环中,每当有人退出圈子时,将他的位置用-1标记,用一个计数器cnt统计报数,当cnt=3时,将当前指针指向的人的位置用-1标记,并将计数器置为0。

4.每次循环结束后,判断圈子中标记为-1的人数是否为n-1,如果是,则跳出循环。最后,圈子中标记不为-1的那个位置就是留下来的那个人的位置,将其对应的编号输出。

5.释放动态内存。

三、代码实现

#include <stdio.h>
#include <stdlib.h>

int main()
{
    
    
    int n, i, cnt = 0;
    printf("请输入n的值:");
    scanf("%d", &n);

    // 动态内存分配申请一个大小为n的int型数组,模拟圆圈
    int* circle = (int*)malloc(n * sizeof(int));
    for (i = 0; i < n; i++)
    {
    
    
        circle[i] = i + 1; // 初始化圆圈中的每个人的编号
    }

    int* p = circle; // 从第一个人开始报数,指针p指向circle[0]

    while (1)
    {
    
    
        if (*p != -1) // 如果当前位置的人没有被退出圈子,那么就开始报数
        {
    
    
            cnt++; // 报数+1
        }
        if (cnt == 3) // 如果报数为3,那么退出圈子
        {
    
    
            *p = -1; // 退出圈子,将此位置用-1标记
            cnt = 0; // 计数器清零
        }

        if (p - circle == n - 1) // 如果已经到了圈子的末尾,那么就回到开头
        {
    
    
            p = circle;
        }
        else
        {
    
    
            p++; // 指针后移,指向下一个人
        }

        int out_count = 0; // 统计已经退出圈子的人数
        for (i = 0; i < n; i++)
        {
    
    
            if (circle[i] == -1)
            {
    
    
                out_count++;
            }
        }
        if (out_count == n - 1) // 如果圆圈中只剩下一个人,那么就退出循环
        {
    
    
            break;
        }
    }

    for (i = 0; i < n; i++)
    {
    
    
        if (circle[i] != -1) // 找到圆圈中最后剩下的那个人的编号
        {
    
    
            printf("最后留下的是原来的第%d号的那位\n", circle[i]);
            break;
        }
    }

    free(circle); // 释放动态内存
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/ikun10001/article/details/130511285