题面
小缘开了一家公司,生意很好,每天都会收到很多订单,自动交易系统会自动给这些订单生成没有重复的订单编号。但是有一天,系统出现了未知的错误,导致当天的订单编号可能有重复的,这可把小缘急坏了。你可以帮助小缘按照规则给这些订单重新编号吗?
按照时间先后顺序给出 NN 个正整数作为原订单编号,你需要按照规则依次赋予这些订单新的编号,对于任意一个订单,要找到大于等于其原订单编号且未被使用过的(没有被之前的订单作为新的订单编号)的最小整数,作为它的新订单编号。
例如: 原订单编号依次为1 2 3 1,则新订单编号应该为1 2 3 4 (前3个订单的原订单编号都没有使用过,所以用其原订单编号即可,对于第四个订单,原订单编号为1,而1, 2, 3都已经被使用过,所以新订单编号为4)。
输入格式
第一行输入一个整数 N(1≤N≤5×105)(1≤N≤5×105)。
第二行输入 N 个数 ai (1≤ai≤109)作为原订单编号。
输出格式
输出一行,包含 NN 个整数为新的订单编号。
#include <iostream>
#include <map>
#include <cstring>
#include <set>
#include <stdio.h>
using namespace std;
set<pair<int, int> >ss;
void insert(int l, int r) {
if (l > r) return;
if (l <= r) ss.insert({ r,l });
}
int main(void) {
int n, x;
cin >> n;
ss.insert(make_pair(2e9, 1));
for (int i = 1; i <= n; ++i) {
cin >> x;
auto iter = ss.lower_bound(make_pair(x, 0));
if (iter->second <= x) {
cout << x << " ";
insert(iter->second, x - 1);
insert(x + 1, iter->first);
ss.erase(iter);
}
else {
cout << iter->second << " ";
insert(iter->second + 1, iter->first);
ss.erase(iter);
}
}
return 0;
}
Reward:
1.熟悉了set的相关操作,erase原来还能这么删的,以及pair的有关用法
2.lower_bound的用法以及返回值的类型,以及auto的使用
Think:
1.为什么采用set来写 set可以自动排序
2.为什么在一个区间把大的数字放在前面? 和lower_bound有关
3.为什么要另外写一个函数,不直接插入?