第四章 - The Dole Queue - uva 133
In a serious attempt to downsize (reduce) the dole queue, The New National Green Labour RhinocerosParty has decided on the following strategy. Every day all dole applicants will be placed in a largecircle, facing inwards. Someone is arbitrarily chosen as number 1, and the rest are numbered counterclockwiseup to N (who will be standing on 1’s left). Starting from 1 and moving counter-clockwise,one labour official counts off k applicants, while another official starts from N and moves clockwise,counting m applicants. The two who are chosen are then sent off for retraining; if both officials pickthe same person she (he) is sent off to become a politician. Each official then starts counting againat the next available person and the process continues until no-one is left. Note that the two victims(sorry, trainees) leave the ring simultaneously, so it is possible for one official to count a person alreadyselected by the other official.InputWrite a program that will successively read in (in that order) the three numbers (N, k and m; k, m > 0,0 < N < 20) and determine the order in which the applicants are sent off for retraining. Each set ofthree numbers will be on a separate line and the end of data will be signalled by three zeroes (0 0 0).OutputFor each triplet, output a single line of numbers specifying the order in which people are chosen. Eachnumber should be in a field of 3 characters. For pairs of numbers list the person chosen by the counterclockwiseofficial first. Separate successive pairs (or singletons) by commas (but there should not be atrailing comma).Note: The symbol ⊔ in the Sample Output below represents a space.Sample Input10 4 30 0 0Sample Output␣␣4␣␣8,␣␣9␣␣5,␣␣3␣␣1,␣␣2␣␣6,␣10,␣␣7
分析:
看似简单,可废了不少时间去写……怎么去设计函数,使代码简洁高效是我们需要考虑的。
注意,每次两个人选人的时候,比如:a从1到6选了6(k=6),这时,6还没有被移去,b从10选到5(m=6)6也算进去
注意,怎么构造go函数使得,正序,逆序都可以调用到它是很重要的。
之前写的代码,每进行一轮挑选,就用一个从1到n的for循环,判断是否都被选完……这个做法是非常蠢的。
定义一个变量记录还剩的人数,当变量为0是退出就行了。(这是我从这道题学到的方法)
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,k,m;
int a[25];
int go(int pos,int turn,int x){//从pos开始向turn方向走x步
for(int i=pos;;i=(i+turn)%n){
if(i==0)i=n;
if(a[i]!=0&&x!=0)x--;
if(x==0)return i;
}
}
int main(){
while(scanf("%d%d%d",&n,&k,&m)!=EOF){
if(n==0&&k==0&&m==0)break;
int left=n;
for(int i=1;i<=n;i++){
a[i]=i;
}
int l=0,r=n+1;
while(left){
l=go(l+1,1,k);
r=go(r-1,-1,m);
if(l==r)left--;
else left-=2;
if(l==r){printf("%3d",a[l]);a[l]=0;}
else {printf("%3d%3d",a[l],a[r]);a[l]=0;a[r]=0;}
if(left!=0)printf(",");
else printf("\n");
}
}
}