Camp 订单编号

题面

小缘开了一家公司,生意很好,每天都会收到很多订单,自动交易系统会自动给这些订单生成没有重复的订单编号。但是有一天,系统出现了未知的错误,导致当天的订单编号可能有重复的,这可把小缘急坏了。你可以帮助小缘按照规则给这些订单重新编号吗?

按照时间先后顺序给出 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.为什么要另外写一个函数,不直接插入?


  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值