zoukankan      html  css  js  c++  java
  • 【洛谷】【treap/堆】P2073 送花

    【题目描述:】

    这些花都很漂亮,每朵花有一个美丽值W,价格为C。

    小明一开始有一个空的花束,他不断地向里面添加花。他有以下几种操作:

    操作 含义

    1 W C 添加一朵美丽值为W,价格为C的花。

    3 小明觉得当前花束中最便宜的一朵花太廉价,不适合送给小红,所以删除最便宜的一朵花。

    2 小明觉得当前花束中最贵的一朵花太贵,他心疼自己的钱,所以删除最贵的一朵花。

    -1 完成添加与删除,开始包装花束

    若删除操作时没有花,则跳过删除操作。

    如果加入的花朵价格已经与花束中已有花朵价格重复,则这一朵花不能加入花束。

    请你帮小明写一个程序,计算出开始包装花束时,花束中所有花的美丽值的总和,以及小明需要为花束付出的总价格。

    【输入格式:】

    若干行,每行一个操作,以-1结束。

    【输出格式:】

    一行,两个空格隔开的正整数表示开始包装花束时,花束中所有花的美丽值的总和。以及小明需要为花束付出的总价格。

    /*
    输入样例#1: 
    1 1 1
    1 2 5
    2
    1 3 3
    3
    1 5 2
    -1
    输出样例#1: 
    8 5
    */
    输入输出样例

    【算法分析:】

    方法一:红黑树.

      手写红黑树是不可能的,但是可以用stl里的map水(set好像也可以不过应该比map慢一些)

    map里的key-value其实就是pair,而且map里的元素是有序的:

      默认按key从小到大排,所以求c的最值时应把make_pair(c, w)加入map

    所以删除最小的元素就是删除map中的第一个元素,删除最大的元素就是删除map中的最后一个。

    删除操作可以通过erase(iterator)来实现,定义一个map<int, int> a,

      则第一个元素的位置为a.begin()

      最后一个元素的位置就是 --a.end()

    最后累加的时候通过迭代器遍历map,用a->first和a->second访问key, value的值

    去重的话加一个bool数组去重就好

     1 //P2073 送花
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<map>
     6 #define mkp make_pair
     7 #define fi first
     8 #define se second
     9 using namespace std;
    10 
    11 const int MAXN = 1000000 + 1;
    12 
    13 map<int, int> a;
    14 bool vis[MAXN];
    15 
    16 int main() {
    17     int fl, w, c;
    18     while(scanf("%d", &fl) == 1 && fl != -1) {
    19         if(fl == 1) {
    20             scanf("%d%d", &w, &c);
    21             if(vis[c]) continue;
    22             a.insert(mkp(c, w));
    23             vis[c] = 1;
    24         }
    25         if(fl == 2) {
    26             if(!a.size()) continue;
    27             map<int, int>::iterator it;
    28             it = a.end();
    29             --it; vis[it->fi] = 0;
    30             a.erase(it);
    31         }
    32         if(fl == 3) {
    33             if(!a.size()) continue;
    34             map<int, int>::iterator it;
    35             it = a.begin();
    36             vis[it->fi] = 0;
    37             a.erase(it);
    38         }
    39     }
    40     long long sum1 = 0, sum2 = 0;
    41     map<int, int>::iterator it;
    42     for(it=a.begin(); it!=a.end();++it)
    43         sum1 += it->se, sum2 += it->fi;
    44     printf("%lld %lld
    ", sum1, sum2);
    45 }
    map实现

    方法二:堆

      要求最大值和最小值并删除,很容易想到通过堆来实现

    开一个小根堆p1和一个大根堆p2,

    vis[c]表示价格为c的花的美丽度,vis[c]=0表示没有这朵花

    每次读入把c分别push进两个堆里,记录vis[c]

    两个变量sum1, sum2分别累加c和w,

    在删除的时候sum1, sum2要分别减去c和vis[c]

     1 //P2073 送花
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 
     8 const int MAXN = 1000000 + 1;
     9 
    10 int vis[MAXN];
    11 priority_queue<int, vector<int>, greater<int> > q1;
    12 priority_queue<int> q2;
    13 
    14 int main() {
    15     int fl, w, c;
    16     long long sum1 = 0, sum2 = 0;
    17     while(scanf("%d", &fl) == 1 && fl != -1) {
    18         if(fl == 1) {
    19             scanf("%d%d", &w, &c);
    20             if(vis[c]) continue;
    21             q1.push(c), q2.push(c);
    22             vis[c] = w;
    23             sum1 += w, sum2 += c;
    24         }
    25         if(fl == 2) {
    26             while(!q2.empty() && !vis[q2.top()]) q2.pop();
    27             if(q2.empty()) continue;
    28             int t = q2.top();
    29             sum1 -= vis[t];
    30             sum2 -= t;
    31             vis[t] = 0;
    32             q2.pop();
    33         }
    34         if(fl == 3) {
    35             while(!q1.empty() && !vis[q1.top()]) q1.pop();
    36             if(q1.empty()) continue;
    37             int t = q1.top();
    38             sum1 -= vis[t];
    39             sum2 -= t;
    40             vis[t] = 0;
    41             q1.pop();
    42         }
    43     }
    44     printf("%lld %lld
    ", sum1, sum2);
    45 }
    堆实现
  • 相关阅读:
    20140630 科技脉搏-互联网精神之“我不是为了输赢,我就是认真”
    iOS 获取本地视频的缩略图
    iOS App与iTunes文件传输的方法和对iOS App文件结构的说明
    罗振宇自媒体品牌“罗辑思维”估值1亿背后:媒体通往社群之路
    20140622 科技脉搏 -互联网思维之“一群人团结起来占其他人便宜”
    20140616 科技脉搏 -最大颠覆来自创业公司与边缘产业
    关于流媒体(m3u8)的下载与播放
    20140608 科技脉搏 -下半身需求是人类共同需求,有多少人就有多大市场
    IOS遍历未知对象属性、函数
    iOS中使用 Reachability 检测网络
  • 原文地址:https://www.cnblogs.com/devilk-sjj/p/9065586.html
Copyright © 2011-2022 走看看