C++&STL&multiset&vector 杭电多校第三场 1007 find the answer && ccpc 网络赛Shuffle Card

本文详细介绍了C++标准模板库中的multiset容器,包括其基于红黑树的实现原理,基本操作如插入、查找和删除等。并通过示例代码展示了如何使用multiset进行元素的管理,以及与vector在效率上的对比,适用于需要处理重复元素并保持有序的数据结构场景。
摘要由CSDN通过智能技术生成

multiset 和 set 是基于红黑树实现的
官方的函数参考网址
基本用法
insert
erase
find
for(auto temauto:ss){}
multiset
multiset<int,greater> 递减
multiset<int,less> 递增

//
//  main.cpp
//  multiset
//
//  Created by 陈冉飞 on 2019/7/30.
//  Copyright © 2019 陈冉飞. All rights reserved.
//

#include <iostream>
#include <set>
using namespace std;

multiset<int>ss;

multiset<int,greater<int>>greaterss;

multiset<int,less<int>>lessss;

int main(int argc, const char * argv[]) {
    ss.insert(8);
    ss.insert(3);
    ss.insert(7);
    ss.insert(1);
    ss.insert(10);
    for(auto temauto:ss){
        cout<<temauto<<endl;
    }
    
    cout<<"***********"<<endl;
    greaterss.insert(8);
    greaterss.insert(3);
    greaterss.insert(7);
    greaterss.insert(1);
    greaterss.insert(10);
    for(auto temauto:greaterss){
        cout<<temauto<<endl;
    }
    
    cout<<"***********"<<endl;
    lessss.insert(8);
    lessss.insert(3);
    lessss.insert(7);
    lessss.insert(1);
    lessss.insert(10);
    for(auto temauto:lessss){
        cout<<temauto<<endl;
    }
    
    cout<<"***********"<<endl;
    //找到某特定元素 并删除
    ss.erase(ss.find(7));
    //指针遍历
    auto j = ss.end();
    j--;
    for (; j!=ss.begin(); j--) {
        cout<<*j<<endl;
    }
    
    return 0;
}

在这里插入图片描述


顺便贴上vector的常见函数find、insert插入函数的用法

用vector是超时的,要直接通过倒顺叙倒着输出,然后在原序列中找没有输出的。

//
//  main.cpp
//  1006
//
//  Created by 陈冉飞 on 2019/8/23.
//  Copyright © 2019 陈冉飞. All rights reserved.
//

#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
#include <vector>
vector<int>b;
int n,m,c,tem,tnum;

int main(int argc, const char * argv[]) {
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++) {scanf("%d",&c);b.push_back(c);}
    while (m--) {
        scanf("%d",&tem);
        vector<int>::iterator it = find(b.begin(), b.end(), tem);
        tnum = *it;
        b.erase(it);
        b.insert(b.begin(), tem);
//        cout<<endl<<endl;
//        for (int i = 0; i < b.size(); i++) printf("%d ",b[i]);
    }
    for (int i = 0; i < b.size(); i++) printf("%d ",b[i]);
    return 0;
}
//
//  main.cpp
//  1006
//
//  Created by 陈冉飞 on 2019/8/23.
//  Copyright © 2019 陈冉飞. All rights reserved.
//

#include <iostream>
using namespace std;
#define maxn 100010
bool is[maxn];
int n,m,tem,tnum,a[maxn],c,b[maxn];


int main(int argc, const char * argv[]) {
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++) scanf("%d",&a[i]);
    for (int i = 1; i <= m; i++) scanf("%d",&b[i]);
    for (int i = m; i >= 1; i--) if(!is[b[i]]){printf("%d ",b[i]);is[b[i]] = 1;}
    for (int i = 1; i <= n; i++) if(!is[a[i]])printf("%d ",a[i]);
    return 0;
}

杭电多校第三场1007
用优先队列将最大的放到最后这样会超时,但是用multiset不会超时
(也可以用线段树,记录区间之和,然后利用单点修改)

//
//  main.cpp
//  hdu_1007_multiset_m
//
//  Created by 陈冉飞 on 2019/7/30.
//  Copyright © 2019 陈冉飞. All rights reserved.
//

#include <iostream>
#include <set>
#define maxn 200050
typedef long long ll;
using namespace std;

multiset<int>ss;
int a[maxn];

int main(int argc, const char * argv[]) {
    int T,total;
    ll stdm;
    scanf("%d",&T);
    while (T--) {
        ss.clear();
        scanf("%d%lld",&total,&stdm);
        for (int i = 0; i < total; i ++) {
            scanf("%d",&a[i]);
        }
        int tem = 0;
        ll sum = 0,temsum;
        for (int i = 0; i < total; i++) {
            temsum = sum;
            int cnt = 0;
            if(temsum+a[i] > stdm){
                //由于指向multiset的指针的数据类型不是int 可以定义为auto
                auto j = ss.end();   //j为队尾的元素
                while(temsum + a[i] > stdm){
                    //指针前移,并且通过 * 来取出值
                    j--;
                    temsum -= *j;
                    cnt++;
                }
            }
            cout<<tem+cnt<<" ";
            auto j = ss.end();
            ss.insert(a[i]);
            sum += a[i];
            while (sum>stdm) {
                j--;
                sum-=*j;
                ss.erase(ss.find(*j));
                tem++;
            }
        }
        cout<<endl;
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值