1. 程式人生 > >例題4-3 救濟金髮放(The Dole Queue, UVa 133)題解——23行程式碼

例題4-3 救濟金髮放(The Dole Queue, UVa 133)題解——23行程式碼

題目描述

The Dole Queue - UVA 133題目描述

題意解析

n(n<20)個人站成一圈,逆時針編號為1~n。有兩個官員,A從1開始逆時針數,B從n開始順時針數。在每一輪中,官員A數k個就停下來,官員B數m個就停下來(注意有可能兩個官員停在同一個人上)。接下來被官員選中的人(1個或者2個)離開隊伍。輸入n,k,m輸出每輪裡被選中的人的編號(如果有兩個人,先輸出被A選中的)。注意:輸出的每個數應當恰好佔3列。

演算法設計

定義一個長度為n的bool型陣列A,元素下標代表題目中的編號-1,元素內容為false時表示該元素還沒有被選中,元素內容為true時表示該元素已被選中。定義兩個索引iijj,分別表示官員A和官員B挑中的人,i

i遞增表示逆時針數數,jj遞減表示順時針數數,在數數過程中要跳過為true的元素。一輪遊戲結束的條件是陣列中不再有為false的元素。

C++程式碼

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,k,m;
    while(~scanf("%d%d%d",&n,&k,&m)&&!(n==0&&k==0&&m==0)){
        bool A[n]={false};
        int i=0,j=n-1,order=
0;//order是為了決定是否輸出逗號 while(find(A,A+n,false)!=A+n){//陣列中找不到為false的元素時跳出迴圈 for(int num=0;true;i=(i+1)%n)//i遞增逆時針數k個沒有被選中的人 if(!A[i]&&++num==k) break; for(int num=0;true;j=(n+j-1)%n)//j遞減順時針數m個沒有被選中的人 if(!A[j]&&++
num==m) break; printf("%s%3d",order++==0?"":",",i+1); if(j!=i) printf("%3d",j+1); A[i]=A[j]=true; } puts(""); } return 0; }