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,这个容器可以识是的维护区间的顺序,而且可以删除任意元素,而且还可以存重复元素。