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;
}
不忘初心方得始终