士兵队列训练问题题解(杭电1276)

https://acm.hdu.edu.cn/showproblem.php?pid=1276

模拟:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
1 3 5 7 9 11 13 15 17 19
1 3 7 9 13 15 19
1 7 13 19
1 7 19 

可以用多种方式做,这里用队列做
开个flag标志,flag为0按偶数去掉,flag为1按三倍去掉
size()<4结束筛选
接下来讨论删除
设置两个队列,一个个出队,循环操作,遇到待删元素直接跳过即可
开个计数器,取余判断是否跳过
 

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
bool judge(queue<int> a) { //判断队伍是否少于4人,是返回1,否则0
	if(a.size()<4)	return 1;
	else	return 0;
}
int out(queue<int> &a,queue<int> &b,int &flag) { //一轮出列 ,a出列的结果赋值给b,并清空a,如果小于4人返回1,否则0 
	int cnt=1;
	int sum=a.size();
	if(!flag) { //偶倍出列 
		while(cnt<=sum) {
			if(cnt%2) {
				b.push(a.front());
				a.pop();
				cnt++;
			} else {
				a.pop();
				cnt++;
			}
		}
		flag=1;
	} else {//三倍出列 
		while(cnt<=sum)
		{
			if(cnt%3) {
				b.push(a.front());
				a.pop();
				cnt++;
			} else {
				a.pop();
				cnt++;
			}
		}
		flag=0;
	}
	if(judge(b))	return 1; //经过一轮出列后b符合条件 		
	else	return 0;
}
void print(queue<int> a)//打印a并清空a 
{
	int cnt=a.size();
	for(int i=1;i<cnt;i++)
	{
		printf("%d ",a.front());
		a.pop();
	}
	printf("%d\n",a.front());
	a.pop();
}
int main() {
	int N;
	scanf("%d",&N);
	while(N--) {
		int sum;
		scanf("%d",&sum);
		queue<int> a,b;
		for(int i=1; i<=sum; i++) {
			a.push(i);
		}
		if(sum<4)
		{
			print(a);
			continue;
		}
		int flag=0;
		int ans;
		do
		{	
			ans=out(a,b,flag);//a出列赋值给b
			if(ans)//结束 
			{
				print(b);
				break;
			}else{
				ans=out(b,a,flag);
				if(ans)//结束 
				{
					print(a);
					break;
				}
			}
		}while(1);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值