题目大意:输入n,m,k。一共n个人,面向内,围成一个圈,从其中一个标号为1,逆时针标记为2~n(即1的右边)。A决定从1号开始(包括1),逆时针数第m个人,B决定从n号开始(包括n)顺时针数第k个人。无论是否同一人,将他放出圆圈,继续A上次放走的下一个人的位置,逆时针数第m个人,从B上次放走的下一个人的位置,顺时针数k个人。继续这个步骤,直到全部放走。输出放走的情况。
解题思路:模拟一个数组,如果放走了,数组的值改为0,循环时,不考虑这点,循环到尾端(A)或首段(B决定),手动改变位置到首或尾。如果点有值(非0)要继续数的人头减去一,直到继续数的人头数为0时。返回位置。没返回两个位置,就输出。注意格式。
ac代码:
#include <iostream>
using namespace std;
int vis[30];
int get_pos(int pos, int m, int temp, int n)
{
int cnt=m;
if (temp){
for (int i=pos; i<=n; i++){
if (i == n)
i = 0;
if (vis[i])
cnt--;
if (!cnt)
return i;
}
}
else{
for (int i=pos; i>=-1; i--){
if (i == -1)
i = n - 1;
if (vis[i])
cnt--;
if (!cnt)
return i;
}
}
}
int main()
{
int n, m, k, size;
int pos1, pos2;
while (scanf("%d%d%d", &n, &m, &k)!=EOF && n && m && k){
for (int i=0; i<n; i++)
vis[i] = i + 1;
pos1 = 0, pos2 = n-1, size = n;
while (size){
pos1 = get_pos(pos1, m, 1, n);
pos2 = get_pos(pos2, k, 0, n);
vis[pos1] = vis[pos2] = 0;
if (pos1 == pos2){
printf("%3d", pos1+1);
size--;
}
else{
printf("%3d%3d", pos1+1, pos2+1);
size -= 2;
}
if (size)
printf(",");
}
printf("\n");
}
return 0;
}