1 条题解

  • 0
    @ 2026-6-19 10:30:44

    📝 题目大意

    给定一个容量为 GG 毫升的玻璃杯和一个容量为 MM 毫升的马克杯(G<MG < M),初始均为空。按照三条规则进行 KK 次操作:玻璃杯满则倒空,马克杯空则装满,否则从马克杯向玻璃杯倒水直到马克杯为空或玻璃杯装满。求最终两杯中的水量。

    💡 解题思路

    1. 题目分析K100K \leq 100M1000M \leq 1000,数据范围极小,直接模拟 KK 次操作即可,无需寻找循环节或数学公式。
    2. 算法推导
      • 维护两个变量 glassmug 分别表示玻璃杯和马克杯的当前水量,初始均为 00
      • 循环 KK 次,每次按优先级判断:
        • 规则一:若 glass == G,则 glass = 0(倒空玻璃杯);
        • 规则二:否则若 mug == 0,则 mug = M(装满马克杯);
        • 规则三:否则执行倒水操作,倒水量为 min(mug, Gglass)\min(\text{mug},\ G - \text{glass}),即从马克杯能倒出的水与玻璃杯剩余容量中的较小值。更新 glass += pourmug -= pour
    3. 边界与细节
      • 规则有严格的优先级:先判断玻璃杯是否满,再判断马克杯是否空,最后才是倒水。使用 if-else if-else 结构即可保证。
      • 倒水量用 min(mug, G - glass) 计算,避免手动分类讨论,简洁且不易出错。
      • 注意 G<MG < M 保证了马克杯容量大于玻璃杯,但即使不成立,代码逻辑依然正确。

    ⏱️ 复杂度分析

    • 时间复杂度O(K)O(K),仅需模拟 KK 次操作。
    • 空间复杂度O(1)O(1),仅使用常数个变量。

    💻 标准代码 (C++)

    #include <iostream>
    using namespace std;
    int main() {
        int K, G, M;
        cin >> K >> G >> M;
        int glass = 0, mug = 0;                 // 初始两杯皆空
        for (int i = 0; i < K; i++) {           // 模拟 K 次操作
            if (glass == G) {                   // 规则一:玻璃杯满则倒空
                glass = 0;
            } else if (mug == 0) {              // 规则二:马克杯空则装满
                mug = M;
            } else {                            // 规则三:从马克杯向玻璃杯倒水
                int pour = min(mug, G - glass); // 倒水量 = 马克杯水量 与 玻璃杯剩余容量 的较小值
                glass += pour;
                mug -= pour;
            }
        }
        cout << glass << " " << mug << endl;    // 输出最终水量
        return 0;
    }
    
    • 1

    信息

    ID
    761
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者