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

本文介绍了一个救济金发放的算法实现,n个人围成圈,通过两名官员按特定规则选择人员离开,直至所有人被选中。文章提供了完整的C语言程序代码,并详细解释了核心函数的工作原理。

救济金发放

问题描述
n(n<20)个人站成一圈,逆时针编号为1~n。有两个官员,A从1开始逆时针数,B从n开始顺时针数。在每一轮中,官员A数k个就停下来,官员B数m个就停下来(注意有可能来两个官员停在同一人上)。接下来被官员选中的人(1个或者2个)离开队伍。
输n,k,m,输出每轮里被选中的人的编号(如果有两个人,先输出被A选中的)。例如,n=10,k=4,m=3,,输出为4 8,9 5, 3 1,2 6,10 7。注意,输出的每数应当 恰好占三列。

#include <stdio.h>
#define maxn 25

int n, k, m, a[maxn];
// 逆时针走t步,步长是d(-1表示顺时针走),返回新位置 
int go (int p, int d, int t) {
    while (t--) {
        do {
            p = (p+d-1+n) % n + 1;
        } while (a[p] == 0);
    }
    return p;
} 
int main() {
    while (scanf("%d%d%d", &n, &k, &m) == 3 && n) {
        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--;
            if (p2 != p1) {
                printf("%3d", p2);
                left--;
            }
            a[p1] = a[p2] = 0;
            if (left) 
                printf(", ");
        } 
        printf("\n");       
    }
    return 0;
} 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值