强化练习4:有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数), 凡报到3的人退出圈子,问最后留下的是原来第几号。

本文提供了一个使用C语言解决约瑟夫环问题的程序示例。通过不断移除编号为3的人直至只剩一人,该程序能找出最终留下的成员编号。

题目:

有n个人围成一圈,顺序排号,从第一个开始报数(从1到3报数),

凡报到3的人退出圈子,问最后留下的是原来第几号。

程序如下:

#include <stdio.h>



int main() 
{ 
	int a[100]; 
	int i,n,q;
	int p = 0; 
	printf("input number:"); 
	scanf("%d",&n); 
	q = n; 
	for (i = 0; i < n; i++) 
		a[i] = i+1; 
	for(i = 0; ; i++) 
	{ 
		if(i == n) 
			i = 0; 
		if(a[i] != 0)
			p++;
		else 
			continue; 
		if(p%3 == 0)
		{
			a[i] = 0; q--;
		} 
	
	if(q == 1) 
		break; 
	} 
	
	for(i = 0; i < n; i++) 
	{
		if(a[i] != 0) 
		printf("spare: %d\n", a[i]); 
	}
	return 0;
}



这是一个经典的动态规划或模拟的题,可以通过循环和条件判断来解决。这个题通常被称为“环形数组报数游戏”。下面是解题的基本思路: 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; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值