新兵队列问题(队列)

某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。 

Input

本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。 

Output

共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。 

Sample Input

2
20
40

Sample Output

1 7 19
1 19 37

这里就是用两个队列,来回的倒数据,知道队列的长度<=3,就是满足条件的了

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,num,flag;
		queue<int> q1,q2;
		cin>>n;
		for(int i=1;i<=n;i++)
		    q1.push(i);
		if(q1.size() <=3){//若是人数本来就小于3 
			cout<<q1.front() ;
			q1.pop() ;
			while(!q1.empty()  ){
				cout<<" "<<q1.front() ;
				q1.pop() ;
			}
			cout<<endl;
			continue;//    ...........
		} 
		while(1){//两个队列轮流的换 
			num=1;
			flag=2;//mod 2
			while(!q1.empty() ){
				if(num%flag!=0)
				    q2.push(q1.front() );
				q1.pop() ; 
				num++;
			}
			if(q2.size() <=3){
			    cout<<q2.front() ;
			    q2.pop() ;
			    while(!q2.empty()  ){
				    cout<<" "<<q2.front() ;
				    q2.pop() ;
			    }
			    break;//    ...........
			} 
			num=1;  //现在q1又是一个空的队列了 
			flag=3;//mod 3   
			while(!q2.empty() ){
				if(num%flag!=0)
				    q1.push(q2.front() );
				q2.pop() ; 
				num++;
			}
			if(q1.size() <=3){
			    cout<<q1.front() ;
			    q1.pop() ;
			    while(!q1.empty()  ){
				    cout<<" "<<q1.front() ;
				    q1.pop() ;
			    }
			    break;//  ...........
			} 
		}
		cout<<endl;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/red_red_red/article/details/87923497