模拟算法实战:牛客25380题分层倒酒问题的优雅解法
一、问题背景与理解
牛客25380题描述了一个有趣的分层倒酒问题:有n层容器,每层有固定容量。我们需要处理两种操作:查询某层的当前酒量,以及从指定层开始倒入一定量的酒(当一层装满后,多余酒量会自动流向下一层)。这是一个典型的模拟类问题,考验对实际问题抽象建模和流程控制的能力。
二、完整代码实现(带详细注释)
#include <iostream> #include <vector> using namespACe std; int main() { ios::sync_with_stdio(false); // 禁用C与C++的输入输出同步,提升IO速度 cin.tie(nullptr); // 解除cin与cout的绑定,进一步提速 int n, m; // n-层数,m-操作次数 cin >> n >> m; vector<long long> capacity(n); // 每层的最大容量 vector<long long> current(n, 0); // 每层当前酒量,初始为0 // 读取每层初始容量 for (int i = 0; i < n; ++i) { cin >> capacity[i]; } while (m--) { // 处理m个操作 int op; cin >> op; if (op == 1) { // 查询操作 int k; cin >> k; cout << current[k-1] << "\n"; // 输出第k层当前酒量(转换为0-based) } else { // 倒酒操作 int x; // 起始层(1-based) long long v; // 倒酒量 cin >> x >> v; x--; // 转换为0-based索引 // 从指定层开始倒酒 while (v > 0 && x < n) { // 还有酒未倒完且还有下层 long long available = capacity[x] - current[x]; // 当前层剩余容量 if (v <= available) { // 当前层可以容纳全部剩余酒量 current[x] += v; v = 0; // 酒已倒完 } else { // 当前层会被装满 current[x] = capacity[x]; // 装满当前层 v -= available; // 减去已倒入的量 x++; // 处理下一层 } } } } return 0; }
三、算法核心思想
模拟过程:忠实按照题目描述的物理过程进行模拟
状态维护:使用两个数组分别记录各层的容量和当前酒量
操作处理:区分查询和倒酒两种操作类型
溢出处理:自动将多余酒量流向下一层的逻辑实现
四、关键技巧分析
IO优化:使用
ios::sync_with_stdio(false)
和cin.tie(nullptr)
加速输入输出索引处理:注意1-based和0-based索引的转换
循环控制:通过
while(v > 0 && x < n)
同时控制酒量和层数边界剩余容量计算:
capacity[x] - current[x]
的巧妙运用
五、复杂度分析
六、扩展思考
如何优化大量倒酒操作的情况?
如果酒可以向上流动(如负压情况),代码需要如何修改?
如何扩展支持删除酒的操作?
原创内容 转载请注明出处