1. 程式人生 > 實用技巧 >UVa133 - The Dole Queue 題解

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;
}