循环报数算法

题目描述:

题目描述
n (n<=100)个学生排队报数,编号为1到n,然后从1数到3循环报数,每次数到3的人就退出,最后留下来的是编号多少的学生。比如,总共4名学生,编号为1,2,3,4。第一次报数1(报数1),2(报数2),3(报数3),4(报数1),3号退出,第二次报数1(报数2),2(报数3),4(报数1),2号退出,依此类推,直到只剩1名学生,输出其编号。

示例输入1
4

示例输出1
1

示例输入2
10

示例输出2
4

算法:

思路:
代码实现:
# include<stdio.h>
int main(){
    int n,k=1,i=0;
    scanf("%d",&n);
    int count=n,end;
    int nums[n];
    for(int i=0;i<n;i++){
        nums[i]=i+1;
    }
    while(count>1){
        //报数
        if(nums[i]!=0){
            nums[i]=k++;
        }
        //报数的值重置
        if(k>3){
            k=1;
        }
        //移除报数为3的数
        if(nums[i]==3){
            nums[i]=0;//置为0,之后不再报数
            count--;//计数减一
        }
        //返回到第一个数
        i++;
        if(i==n){
            i=0;
        }
    }
    for(int j=0;j<n;j++){
        if(nums[j]!=0){
            printf("%d\n",j+1);
        }
    }
}

算法优化:

思路:

1与0标记是否移除,更为易懂

代码实现:
#include <stdio.h>

#define MAX_STUDENTS 100

int findLastStudent(int n);

int main() {
    int n;

    // 获取学生总数
    scanf("%d", &n);

    // 找出最后留下的学生编号
    int lastStudent = findLastStudent(n);

    printf("%d\n", lastStudent);

    return 0;
}

int findLastStudent(int n) {
    // 创建数组表示学生是否已经退出
    int students[MAX_STUDENTS];
    for (int i = 0; i < n; i++) {
        students[i] = 1;  // 初始化为未退出
    }

    int count = 0;  // 记录报数次数
    int index = 0;  // 数到3的学生索引

    while (1) {
        // 数到3的学生退出
        if (students[index] == 1) {
            count++;
            if (count == 3) {
                students[index] = 0;  // 标记为已退出
                count = 0;  // 重新开始报数
            }
        }

        // 移动到下一个学生
        index++;

        // 判断是否回到队伍开头
        if (index == n) {
            index = 0;
        }

        // 检查是否只剩下一个学生
        int remainingStudents = 0;
        int lastStudent = 0;
        for (int i = 0; i < n; i++) {
            if (students[i] == 1) {
                remainingStudents++;
                lastStudent = i + 1;  // 记录最后一个学生的编号(不断更新)
            }
        }

        if (remainingStudents == 1) {//只剩一个学生时,返回编号
            return lastStudent;
        }
    }
}

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值