思路:
1. 使用数组que记录在队伍中的人,数组索引范围是 1~n;
2. 用book标记离开队伍的人
3.用 left 记录队伍剩下的人数,left=0的时候,就可以结束循环;
3.分别从que[p]按顺序,que[q]按逆序遍历数组que,(初始化的时候p=0,q=n+1)。
为了防止q和p超出数组索引范围,可以用取余数的方法:
1. 顺序读取: p = (p-1+n-1)% n + 1;
2. 逆序读取: q = (q+1+n-1)% n + 1;
(例如n=5,则
p=1,2,3,4,5,1,2,3,4,5,1......
q=5,4,3,2,1,5,4,3,2,1,5......
)
区别在于: 顺序的时候为p-1,逆序的时候为p+1;
#include<iostream>
using namespace std;
int main() {
int que[100]; //存放环状数组
bool book[100] = { 0 }; //标记已经离开队伍的人物
int n, i, M, N;
cin >> n; // 人数
if (n == 0)return 0;
cin >> M >> N;
for (i = 1; i <= n; i++) que[i] = i;
int p = 0, q = n + 1;
int left = n; // 队伍剩下的人数
while (left) {
int t = M; //需要走的步数
while (t) {
p = (p + 1 + n - 1) % n + 1; // 向顺序移动一位
if (book[p] == 0) t--; //判断是否可走
}
t = N;
while (t) {
q = (q - 1 + n - 1) % n + 1; // 向逆序移动一位
if (book[q] == 0) t--;//判断是否可走
}
book[p] = 1;
book[q] = 1;
if (p != q) {
cout << que[p] << que[q] << ",";
left -= 2;
}
else {
cout << que[q] << ",";
left--;
}
}
return 0;
}