题目链接——L2-037 包装机
问题分析
这个题目就是模拟了物品在传送带和筐之间的传送过程。传送带用队列模拟,筐用栈模拟。
输入
3 4 4
GPLT
PATA
OMSA
3 2 3 0 1 2 0 2 2 0 -1
输出
根据上述操作,输出的物品顺序是:
MATA
样例分析
初始状态:
- 筐(栈):空
- 行1:
G
P
L
T
- 行2:
P
A
T
A
- 行3:
O
M
S
A
操作步骤:
- 3(取行3的
O
入筐)→ 筐:[O]
- 2(取行2的
P
入筐)→ 筐:[O, P]
- 3(取行3的
M
入筐)→ 筐:[O, P, M]
- 0(输出筐顶
M
)→ 输出:M
,筐:[O, P]
- 1(取行1的
G
入筐)→ 筐:[O, P, G]
- 2(取行2的
A
入筐)→ 筐:[O, P, G, A]
- 0(输出筐顶
A
)→ 输出:A
,筐:[O, P, G]
- 2(取行2的
T
入筐)→ 筐:[O, P, G, T]
- 2(取行2的
A
,但筐已满)→ 先输出筐顶T
,再入A
→ 输出:T
,筐:[O, P, G, A]
- 0(输出筐顶
A
)→ 输出:A
,筐:[O, P, G]
最终输出:
- 按顺序输出的字符:
M
A
T
A
→MATA
解题思路
-
数据结构选择:
- 使用队列数组
queue<char> q[n + 1]
存储每行传送带上的物品。 - 使用栈
stack<char> stk
模拟筐的存储。
- 使用队列数组
-
输入处理:
- 输入
n
、m
和mx
,分别表示传送带行数、每行物品数和筐的最大容量。 - 读取每行传送带的物品,依次存入对应的队列。
- 输入
-
指令处理:
- 循环读取指令
id
:- 如果
id == -1
,结束程序。 - 如果
id == 0
,从筐顶取物并输出(若筐不为空)。 - 如果
id > 0
,从第id
行传送带取物放入筐(若筐满则先取筐顶物品输出)。
- 如果
- 循环读取指令
-
关键点:
- 注意筐的容量限制,满时需先取再放。
- 注意传送带队列和筐的空状态,避免非法操作。
具体见代码
#include<bits/stdc++.h>
#define debug(x) cout<<endl<<"===>"<<#x<<"="<<x<<endl;
#define output(x) cout<<x<<endl;
#define int long long
using namespace std;void solve() {int n, m, mx;//n行,一行m个物品,筐的最大容量cin >> n >> m >> mx;stack<char> stk;//模拟筐的栈queue<char> q[n + 1];//每一行就是一个队列(下标从1开始)for(int i = 1; i <= n; i++) {string s;//一行的物品cin >> s;for(char c : s) q[i].push(c);}int id;while(cin >> id) {if(id == -1) break;//-1即退出if(id == 0) {//输出框顶部if(stk.empty()) continue;//注意筐空//输出筐顶,出栈cout << stk.top();stk.pop();} else {if(q[id].empty()) continue;//注意队列空//将队列的东西放入筐之前,检查是否满了if(stk.size() == mx) {//如果满了,就取筐顶cout << stk.top();stk.pop();}//放筐中,出队列stk.push(q[id].front());q[id].pop();}}
}signed main() {ios::sync_with_stdio(0);cin.tie(0);//while(1)//个人习惯,方便调试solve();return 0;
}