Description
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠 拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报 数直到剩下的人数不超过三人为止。
Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
Sample Input
2
20
40
Sample Output
1 7 19
1 19 37
题目大意就是一个队列报数,第一次12报数,报到2的出列;第二次123报数,报到3的出列;如此循环往复,直到队列人数不超过3.
这里采用两个队列交替使用,对于12报数的情况,只有报到1的才会入另一个队。
对于123的,自然是报到12的入另一个队。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <set> #include <stack> #include <map> #include <queue> #include <string> #include <algorithm> #define LL long long using namespace std; int n; void work() { queue<int> q[2]; bool now = 0; int num; for (int i = 1; i <= n; ++i) q[now].push(i); for (;;) { if (q[now].size() <= 3) break; num = 0; now = !now; while (!q[!now].empty()) { num = num%2+1; if (num != 2) q[now].push(q[!now].front()); q[!now].pop(); } if (q[now].size() <= 3) break; num = 0; now = !now; while (!q[!now].empty()) { num = num%3+1; if (num != 3) q[now].push(q[!now].front()); q[!now].pop(); } } bool flag = false; while (!q[now].empty()) { if (flag) printf(" "); printf("%d", q[now].front()); q[now].pop(); flag = true; } printf(" "); } int main() { //freopen("test.in", "r", stdin); int T; scanf("%d", &T); for (int times = 0; times < T; ++times) { scanf("%d", &n); work(); } return 0; }