士兵队列训练问题--队列(数据结构)

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

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

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

Sample Input
 
   
2 20 40
 

Sample Output
 
   
1 7 19 1 19 37
 

Author
Cai Minglun
 

Source
杭电ACM集训队训练赛(VI)
/*题目要求有两种报数方式,利用两个队列来模拟整个报数的方式,一个队列作为初始士兵存放的表
 另一个队列则保存一次报数后剩下的士兵,两个队列循环,知道最后队列中元素小于4人时,停止操作 
 */
#include 
#include
#include
#include
#define N 5002
using namespace std;

struct Q{
	//定义结构体队列
	int f,r,da[N];
	void init() {
		f=r=0;
	}
	void Push(int a){
		//入队;
		da[r++]=a; 
	}
	int Gettop()
	{
		//取对头元素
		return da[f++]; 
	}
	bool ch(){
		return r-f<4;
	}
	bool empty(){
		//判断队列是否为空; 
		return f==r;
	}
}q[2];
int main()
{
	int T,n,i;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		q[0].init(),q[1].init();
		for(int i=1;i<=n;i++){//进行初始化,将n个人依次加入队列
		  q[0].Push(i); 
		}
		int now=0,pre=1;//now为当前存士兵的队列,pre为另一个工作队列
		i=0;
		while(!q[now].ch()){
			//用两个队列模拟报数过程
			q[pre].init();//一个队列初始化;
			if(i&1){
				//根据i的奇偶性来标识当前的报数的方式;
				while(!q[now].empty())
				{
					q[pre].Push(q[now].Gettop());
					if(q[now].empty())   break;
				    q[pre].Push(q[now].Gettop());
					if(q[now].empty())   break;
					q[now].Gettop(); 
				 } 
			} 
			else {
				while(!q[now].empty())
				{
					q[pre].Push(q[now].Gettop());
					if(q[now].empty())   break;
					q[now].Gettop();
				}
			}
			i^=1;
			swap(now,pre);//交换工作队列 
		} 
		printf("%d",q[now].Gettop());
		while(!q[now].empty())
		{
			printf(" %d",q[now].Gettop());
		}
		cout<

你可能感兴趣的:(数据结构)