UVa133 - The Dole Queue 题解

题目

题目链接

UVa133 - The Dole Queue

题目大意

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

每组数据输入N, k, m(0<N<20)。标志结束的输入为0 0 0

输出被选中的人的编号。注意:输出的每个数应该恰好占3列。

输入样例

10 4 3
0 0 0

输出样例

  4  8,  9  5,  3  1,  2  6, 10,  7

题解

这道题拿到后手推一遍就能理解过程,解题思路自然就出来了。

Then show the code.

#include <stdio.h>

//顺时针为- 逆时针为+
int tra[100];

int main(){
    int N, k, m;
    int pa, pb, outs;
    
    while(scanf("%d%d%d", &N, &k, &m) == 3 && N){
        for(int i=0; i<N; i++)
            tra[i] = i+1;
        //判断是否全部选出去了
        int kase = 0;
        outs = pa = 0; pb=N-1;
        while(1){
            
            //教官A挑人 pa表示该开始数的位置
            for(int i=0; i<k; i++){
                if(!tra[(pa+i)%N]){
                    i--; pa++;
                }
            }
            pa = (pa+k-1)%N;
            //教官B挑人 pb表示该开始数的位置
            for(int i=0; i<m; i++){
                if(!tra[(pb-i+N*10)%N]){
                    i--; pb--;
                }
            }
            pb = (pb-m+1+N*10)%N;
            //挑的人离场
            if(kase++) printf(",");
            if(pa != pb){
                printf("%3d%3d", tra[pa], tra[pb]);
                tra[pa] = tra[pb] = 0;
                outs += 2;
            }
            else{
                printf("%3d", tra[pa]);
                tra[pa] = tra[pb] = 0;
                outs++;
            }
            if(outs == N){
                printf("\n");
                break;
            }
        }
    }


    return 0;
}
posted @ 2020-11-14 20:32  1v7w  阅读(208)  评论(0编辑  收藏  举报