C++ / ACM 自学笔记 · v5.0

P2073 送花

原题入口

对应章节:一、C++ 语法基础 → (十五) STL:容器、迭代器与算法。

(一) 任务与输出目标

按价格插入花、删除最贵或最便宜的花,结束时输出美丽值总和与价格总和。

(二) 建模与推导

map 以价格为键、美丽值为值;价格唯一,emplace 的结果能说明本次花是否加入。只有成功插入才增加两个总和。最便宜是 begin,最贵是 prev(end);删除前从总和减去对应字段,再移除记录。

(三) 手算与过程

加入 (美丽值5,价格10)、(8,20),再删除最贵,剩余总和为 5、10;重复价格的新花不会改变总和。

(四) 带注释实现

完整源文件

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;

void solve() {
    map<int, int> flowers;
    int beauty = 0, cost = 0;
    int op;
    while (cin >> op && op != -1) {
        if (op == 1) {
            int w, c;
            cin >> w >> c;
            if (flowers.emplace(c, w).second) {
                beauty += w;
                cost += c;
            } // 重复价格不加入。
        } else if (!flowers.empty()) {
            auto it = op == 2 ? prev(flowers.end()) : flowers.begin();
            cost -= it->first;
            beauty -= it->second;
            flowers.erase(it); // 总和与实际记录同步修改。
        }
    }
    cout << beauty << ' ' << cost << '\n';
}

signed main() {
    ios::sync_with_stdio(false); // 关闭同步,使用 cin 与 cout 完成输入输出。
    cin.tie(0), cout.tie(0);

    int T = 1; // 本题读入一组数据。
    // cin >> T; // 题目给出测试组数时开启,并在 solve 中处理一组。
    while (T--)
        solve();
}

(五) 复杂度

m 次操作时间 \(O(m\log m)\),空间 \(O(m)\)。

返回本章题解索引 · 返回全部题号索引

查阅笔记正文与全部题解 · Ctrl / ⌘ K