代码源:605、蒟蒻

342 阅读3分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路 logo.png

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目描述

这是3月20日代码源div2的每日一题。

知识点:STL

蒟蒻 - 题目 - Daimayuan Online Judge

便利蜂的货架上摆了一排蒟蒻果冻,搞得鶸尛鱻眼花缭乱......

对于每个果冻,都有一个价格 w 和口感 t。鶸尛鱻有一个购物篮子,在挑选蒟蒻果冻的时候,他有以下几种操作:

  • 操作 1:把一个价格为 w,口感为 t的果冻放入篮子。
  • 操作 2:拿出篮子中 最为廉价 的果冻。
  • 操作 3:拿出篮子中 口感最差 的果冻。(t 越小,口感越差)

鶸尛鱻不喜欢重复,当操作 1 的 价格或口感 与篮中已有果冻重复时,他会立刻将其放回货架。

经过 n 次操作后,鶸尛鱻确定了要购买的若干果冻,请你帮他求出篮子里果冻的总价格。

输入格式

第 1 行一个正整数 n,代表操作次数。

第 2 行至第 (n+1) 行,每行 一个或三个 整数,分别表示 op,w,t。

w 和 t 当且仅当 op=1时存在。

输出格式

输出一个整数,表示篮子里果冻的总价格。

样例输入

6
1 1 1
1 2 5
2
1 3 3
3
1 5 2

样例输出

7

数据规模

所有数据保证 1≤n≤10^5,1≤w,t≤10^6,且保证输入合法

问题分析

与其说算法题,但这题就是教你用stl的(当然有巨佬能手写堆当我没说)。这题可以用map、set或优先队列等能有自动排序能力的容器写(会很方便)。我这里用的是map容器。

准备两个map容器,一个p记录篮子里的果冻的价格,t记录口感。因为map是键值对形式存储,我们对于p,可以以价格为key,口感为val;t可以以口感为key,价格为val。这样记的目的是,我们不论是2操作还是3操作,都可以同时从两个容器里把目标果冻删去。最后只要遍历p里的key,并计算总和即可。(用map也可以判断当前篮子里是否有口感或价格一样的果冻)

说一下这里map用到的几个函数:

  • erase(a):可以删除map里以a为key的键值对。(这里用作2,3操作)

  • count(a):可以判断map中是否有以a为key的键值对。(这里用作判重)

  • begin():是map 的首元素的迭代器(可以把它理解为指针)

AC代码

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>


#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")

#define endl '\n';
typedef long long ll;
typedef pair<int, int>PII;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n,ans=0;
    cin >> n;
    map<int, int>p, t;
    while (n--)
    {
        int st;
        cin >> st;
        if (st == 1)
        {
            int a, b;
            cin >> a >> b;
            if (p.count(a) == 0 && t.count(b) == 0)
            {
                p[a] = b;
                t[b] = a;
            }
        }
        else if (st == 2)
        {
            t.erase(p.begin()->second);
            p.erase(p.begin());
        }
        else if (st == 3)
        {
            p.erase(t.begin()->second);
            t.erase(t.begin());
        }
    }
    ll sum = 0;
    for (auto i : p)sum += i.first;
    cout << sum << endl;
    return 0;
}