救济金发放
题目描述
n(n<20)个人站成一圈,逆时针编号为 1~n。有两个官员,A从1开始逆时针数,B从n开始顺时针数。在每一轮中,官员A数k个就停下来,官员B数m个就停下来(两个官员有可能能停在同一个人上)。接下来被官员选中的1个或2个人离开队伍。
#include<cstdio>
const int N = 20 + 5;
int n, vis[N];
int go(int p, int d, int t) {
while (t--) { // 走t步
do { // 先向下走一步再判断
p = (p + d + n - 1) % n + 1;
} while (vis[p] == 0); // 走到下一个非零数字
}
return p;
}
int main() {
int k, m, A, B, left, cnt = 0;
while (scanf("%d%d%d", &n, &k, &m) == 3 && n) {
for (int i = 1; i <= n; i++) vis[i] = i;
A = n, B = 1, left = n; // 因为A从1开始逆时针数,B从n开始顺时针数
// 所以初始时AB应为下一步的前一个位置
while (left) {
A = go(A, 1, k);
B = go(B, -1, m);
printf("%3d", A); left --;
if (A != B) printf("%3d", B), left --;
vis[A] = vis[B] = 0;
if (left) printf(",");
}
printf("
");
}
return 0;
}