E. Minimum Array Codeforces Round #555 (Div. 3)

E. Minimum Array

题意
给你两个数组,a和b,b的元素顺序可以改变,c[i]=(b[i]+a[i])%n,
求能使c的字典序最小。
思路
这个题一眼看过去就知道要从a[1n]的每个元素依次的匹配b的值,如果b中有(n-a[i])的话,就最优选这个,如果没有的话就选(n-a[i]+1n)中的元素,如果没有
(n-a[i]+1~n)这里面的元素的话就只能从(1,a[i]-1)中挑选,这就是使每一个最优的策略。
但是实现的时候却让我犯难了,本来想用一个数组把b存下来,然后二分查找,如果能找到大于等于n-a[i]+1~n中的元素的话就选,如果不行的话就选元素的第一个。
但是却发现不好删除已经选择过的元素,而且无法实时的维护b数组,自从看了题解,才发现b数组是用一个我没见过的容器存储的。
神奇的multiset。
代码

#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int N=2e5+10;
int a[N],b[N];
multiset<int> mset;
int main()
{
    int n;
    cin>>n;
    for(int i=1 ; i<=n ; i++) cin>>a[i];
    for(int i=1 ; i<=n ; i++)
    {
        int x;
        cin>>x;
        mset.insert(x);
    }
    for(int i=1 ; i<=n ; i++)
    {
        int x=a[i];
        auto it=mset.lower_bound(n-x);
        if(it==mset.end()) it=mset.begin();
        cout<<(x+*it)%n<<" ";
        mset.erase(it);
    }
    cout<<endl;
    return 0;
}

总结
这个题让我学会了一种新的容器,那就是multiset,这个容器可以识是的维护区间的顺序,而且可以删除任意元素,而且还可以存重复元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值