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

该博客介绍了一种环形报数问题,当报到特定数值k时,该人退出,直至只剩一人。文章通过思路解析、C语言实现及测试案例展示了如何找到最后留在圈中的人原来的编号。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

有n个人围成一圈,顺序排号,从第一个开始报数(从1到j报数),凡报到k(k<=j)的人退出圈子,问最后最后留下的是原来第几号的那位.提示:用数组完成

思路:

如果人数大于一,应该一直扫描1~n ,我们可以将每个人放到一个数组中,这样可以利用数组下标进行操作,同样我们还需要一个变量来计数(对应报数的值),当报的数为k时,人数减一,当报到j时,从新计数,循环操作,直到人数为1为止

C实现函数:

/*
函数功能:
函数作者:   zzz

函数参数:   n:总人数
            j:从1到j报数
            k:报到k的人退出圈子
函数返回值: 剩下的人的号

*/
int func(int n,int j,int k)
{
   
   
    //参数检测
	if(n<1||k<1||j<1||k>j)
	return -1;</
这是一个经典的动态规划或模拟的题,可以通过循环和条件判断来解决。这个题通常被称为“环形数组报数游戏”。下面是解题的基本思路: 1. 初始化:设`circle`为一个长度为`n`的数组,表示每个人最初的编。创建一个新的数组`remaining`,同样长度为`n`,用于记录经过一轮报数后剩余员的位置。 2. 循环处理:对于每一次报数(从1到`m`),遍历`circle`数组,当遇到报到`m`的时,将该位置设为`-1`表示已退出,然后更新`remaining`数组中的对应位置为下一个未报过`m`的3. 更新状态:每次报完数后,删除`remaining`数组中所有值为`-1`的元素,因为这些代表已经离开的。 4. 当只剩一个人时,找到`remaining`数组中最后一个非负数,即为最终留下的那个人的原始编。 以下是一个简单的C语言代码实现: ```c #include <stdio.h> int findLastRemaining(int n, int m, int* circle) { int remaining[n]; for (int i = 0; i < n; ++i) { remaining[i] = circle[i]; } while (n > 1) { for (int i = 0; i < n; ++i) { if (remaining[i] == m) { remaining[i] = -1; } else { remaining[i] = (remaining[i] + 1) % m; } } n = count_nonzero(remaining); // 计算非零元素的数量,即剩余数 } return remaining[0]; // 返回最后剩下的那个人的原始编 } // 自定义函数计算数组中非零元素的数量 int count_nonzero(int arr[]) { int count = 0; for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i) { if (arr[i] != 0) { count++; } } return count; } int main() { int n, m; printf("Enter the number of people and the counting limit: "); scanf("%d%d", &n, &m); int* circle = malloc(n * sizeof(int)); printf("Enter their initial positions: "); for (int i = 0; i < n; ++i) { scanf("%d", &circle[i]); } int lastRemaining = findLastRemaining(n, m, circle); printf("The last person standing is originally at position %d.\n", lastRemaining); free(circle); return 0; } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值