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

救济金发放

问题描述
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;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值