L2-041 插松枝

人造松枝加工场的工人需要将各种尺寸的塑料松针插到松枝干上,做成大大小小的松枝。他们的工作流程(并不)是这样的:

  • 每人手边有一只小盒子,初始状态为空。
  • 每人面前有用不完的松枝干和一个推送器,每次推送一片随机型号的松针片。
  • 工人首先捡起一根空的松枝干,从小盒子里摸出最上面的一片松针 —— 如果小盒子是空的,就从推送器上取一片松针。将这片松针插到枝干的最下面。
  • 工人在插后面的松针时,需要保证,每一步插到一根非空松枝干上的松针片,不能比前一步插上的松针片大。如果小盒子中最上面的松针满足要求,就取之插好;否则去推送器上取一片。如果推送器上拿到的仍然不满足要求,就把拿到的这片堆放到小盒子里,继续去推送器上取下一片。注意这里假设小盒子里的松针片是按放入的顺序堆叠起来的,工人每次只能取出最上面(即最后放入)的一片。
  • 当下列三种情况之一发生时,工人会结束手里的松枝制作,开始做下一个:

(1)小盒子已经满了,但推送器上取到的松针仍然不满足要求。此时将手中的松枝放到成品篮里,推送器上取到的松针压回推送器,开始下一根松枝的制作。

(2)小盒子中最上面的松针不满足要求,但推送器上已经没有松针了。此时将手中的松枝放到成品篮里,开始下一根松枝的制作。

(3)手中的松枝干上已经插满了松针,将之放到成品篮里,开始下一根松枝的制作。

现在给定推送器上顺序传过来的 N 片松针的大小,以及小盒子和松枝的容量,请你编写程序自动列出每根成品松枝的信息。

输入格式:

输入在第一行中给出 3 个正整数:N(≤103),为推送器上松针片的数量;M(≤20)为小盒子能存放的松针片的最大数量;K(≤5)为一根松枝干上能插的松针片的最大数量。

随后一行给出 N 个不超过 100 的正整数,为推送器上顺序推出的松针片的大小。

输出格式:

每支松枝成品的信息占一行,顺序给出自底向上每片松针的大小。数字间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

8 3 4
20 25 15 18 20 18 8 5

输出样例:

20 15
20 18 18 8
25 5

笑死了,全场最难题好吧。我差点看题都要晕过去了,这怎么比我看英语阅读理解还要难啊。这namo是什么东西啊。

直接手动开始模拟:

8  小盒子:3   松枝干:4

推送器:20 25 15 18 20 18 8 5 //队列


一开始:							小盒子 空 
								松枝干 空

所以直接从推送器拿:				小盒子 空
								松枝干 20

然后小盒子空,且推送器25不满足		小盒子 25
把25放到小盒子					松枝干 20
	

继续看推送器,15是个冤种			小盒子 25
								松枝干 20 15

然后18,20 都不满足			    小盒子 25 18 20 
全部放进小盒子					松枝干 20 15

惊奇发现小盒子怎么				ans = 20 15
满了呀namo,直接					小盒子 25 18 20 
输出松枝肝			  			松枝干 空


芜湖又开始放松枝干咯先瞅一眼		小盒子 25 18 
从盒子,不是空的直接拿			松枝肝 20


继续看我的盒子哦 还有数还满		小盒子 25
足比我的松枝干小ww,继续虐待你		松枝干 20 18


发现我的小盒子虽然有数但是没用了	小盒子 25
继续去找推送器18 nice!			松枝干 20 18 18

发现我的小盒子虽然有数但是没用了	小盒子 25
继续去找推送器8 nice!			松枝干 20 18 18 8


yi 我的松枝干满了欸				ans = 20 18 18 8		
输出答案吧						小盒子 25
hh								松枝干 空

从我的小盒子拿出25				小盒子 空
namo							松枝干 25


小盒子空了我要赵别人了			小盒子 空
推送器有个5,抢走了 				松枝干 25 5

我擦 怎么小盒子空了				ans = 25 5
推送器也空了啊					小盒子 空
溜了溜了~~~						松枝干 空


end-0-

好了终于看懂了,开始模拟。

盒子是stack, 推送器是queue, 还需要一个松枝干vector,开干咯

#include <bits/stdc++.h>

using namespace  std;

int n, m, k;
queue<int> q;//推送器
stack<int> s;//盒子
void solve(){
	while (1){
		vector<int> v;
		bool flag = 0;
		while(1){
			if (v.empty()){//松枝是空的
				if (!s.empty()){//盒子不是空的
					v.push_back(s.top());//直接放
					s.pop();
				}else if (!q.empty()){//盒子是空的,推送器不是
					v.push_back(q.front());
					q.pop();
				}else{//否则都是空的,推送器是空的
					break;
				}
			}else{//松枝不是空的
				if (!s.empty() && s.top() <= v.back()){//盒子不是空的,且栈顶满足要求
					v.push_back(s.top());
					s.pop();
				}else{//栈顶不满足要求
					while (!q.empty() && s.size() <= m){//找出满足要求的放到松枝上的数
						auto t = q.front();
						if (t <= v.back()){//找到了
							q.pop();
							v.push_back(t);
							break;
						}else{
							if (s.size() == m){//满了
								flag = 1;
								break;
							}else{//不满足,放到栈顶去
								s.push(t);
								q.pop();
							}
						}
					}
					if (q.empty() && (s.empty() || s.top() > v.back())){//如果推送器空了但是栈顶放不了,或者推送器空了盒子也是空的。对应pta情况2
						break;
					}
				}
			}
			if (flag || v.size() == k){//如果盒子满了 或者松枝插满了
				break;
			}
		}
		//输出
		for (int i = 0; i < v.size(); i ++ ){
			if (i != v.size() - 1){
				cout << v[i] << ' ';
			}else{
				cout << v[i] << endl;
			}
		}
		if(s.empty() && q.empty()){
			break;
		}
	}
}

int main()
{
	
	cin >> n >> m >> k;
	
	for (int i = 0; i < n; i ++ ){
		int x;
		cin >> x;
		q.push(x);
	}
	
	solve();

	return 0;
}

 

 

 

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值