题目描述
小科上了初中,开学的第一周是新生军训,小科的教官在进行队列训练时方法非常特殊。一开始N名学生按照顺序从1到N开始编号并排成一个横队。训练时按照如下的规则:从队头开始1至2报数,所有报到2的人出列,剩下的向编号小的方向靠拢,然后再从头开始进行1至3的报数,所有报到3的人出列,剩下的向编号小的方向靠拢,然后循环的进行1到2报数...1到3报数,直至剩余的人数不超过3人为止。最后请你确定一下最终队伍中剩下的人的编号是多少。
输入格式
第一行一个整数T,表示测试数据的组数。接下来T行每行一个整数N表示学生人数,N≤5000
输出格式
对于每组数据,输出一行,队伍中最终剩余的同学的编号
输入输出样例
输入样例1:
2 20 40
输出样例1:
1 7 19 1 19 37
【耗时限制】1000ms 【内存限制】128MB
这一题个人认为难度比较大(作者也困了挺久),可以用队列解答,废话少说,直接放代码
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n,T;
int main()
{
cin>>T;
while(T--){ //多组数据
queue<int> q;
cin>>n;
for(int i=1;i<=n;i++) q.push(i); //把编号传入队列
while(q.size()>3){
int l=q.size(),cnt=0;
for(int i=1;i<=l;i++){ //模拟1-2报数
cnt++;
if(cnt%2==0) q.pop();
else{
q.push(q.front());
q.pop();
}
}
if(q.size()<=3) break; //判断是否可以结束
int cnt1=0;
l=q.size();
for(int i=1;i<=l;i++){ //模拟1-3报数
cnt1++;
if(cnt1%3==0) q.pop();
else{
q.push(q.front());
q.pop();
}
}
if(q.size()<=3) break; //可加可不加
}
for(int i=1;i<=q.size();i++){ //标准队列输出模版
cout<<q.front()<<" ";
q.push(q.front());
q.pop();
}
cout<<endl; //输出换行(注重格式!!)
}
return 0;
}