救济金发放(The Dole Queue,UVa 133)

该文章描述了一个编程问题,涉及n个人围成一圈,两个官员按逆时针和顺时针方向分别按特定步数淘汰人员。程序通过go函数实现移动位置,并在main函数中处理多轮淘汰过程,直到所有人都被淘汰。

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


n(n<20)个人站成一圈,逆时针编号为 1~n。有两个官员,A从1开始逆时针数,B从n开始顺时针数。在每一轮中,官员 A 数个就停下来,官员 B数 m个就停下来(注意有可能两个官员停在同一个人上)。接下来被官员选中的人(1个或者2个)离开队伍。输入 n,k,m 输出每轮里被选中的人的编号(如果有两个人,先输出被 A 选中的)。

例如,n=10,k-4,m=3,输出为48,95,31,26,10,7。注意:输出的每个数应当恰好占3列。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAX 25
int n, k, m, a[MAX];
int go(int p, int d, int t);//p为起始位置,d表示顺时针还是逆时针,走t步
int main()
{
	while (scanf("%d", &n) == 1 && n != 0) {
		scanf("%d%d", &k, &m) == 2;
		for (int i = 1; i <= n; i++) a[i] = i;
		int left = n;
		int p1 = n, p2 = 1;
		while (left) {
			p1 = go(p1, 1, k);
			p2 = go(p2, -1, m);
			printf("%3d", p1);
			left--;
			a[p1] = 0;
			if (p1 != p2) {
				printf("%3d", p2);
				left--;
				a[p2] = 0;
			}

			if (left) printf(",");
		}
		printf("\n");
	}
	return 0;
}

 


                顺时针走和逆时针走两个函数合并,唯一区别只是走1步还是-1步;

                      d = 1  :   p = p%n +1       d = -1 :   p = (p-2+n)%n +1

取余后的取值为0~n-1,因此要再加一,所以d=1时要在原地,d=-1时要后退2步,因此统一后的表达式 p = (p+d+n-1)%n +1;

数k个人实际上是走k-1步,但每次被选中的人要离开队伍,因此要从新的为离开队伍的人开始数,及从离开的人的位置走k步,而第一轮是特殊情况,应该让第一轮的起始位置后退一步,及p1 =n,p2=1;

int go(int p, int d, int t)
{
	while (t--) {
		do {
			p = ((p + d + n - 1) % n) + 1;
		} while (a[p] == 0);
	}
	return p;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值