[codeforces 549]G. Happy Line

[codeforces 549]G. Happy Line

试题描述

Do you like summer? Residents of Berland do. They especially love eating ice cream in the hot summer. So this summer day a large queue of n Berland residents lined up in front of the ice cream stall. We know that each of them has a certain amount of berland dollars with them. The residents of Berland are nice people, so each person agrees to swap places with the person right behind him for just 1 dollar. More formally, if person a stands just behind person b, then person a can pay person b 1 dollar, then a and b get swapped. Of course, if person a has zero dollars, he can not swap places with person b.

Residents of Berland are strange people. In particular, they get upset when there is someone with a strictly smaller sum of money in the line in front of them.

Can you help the residents of Berland form such order in the line so that they were all happy? A happy resident is the one who stands first in the line or the one in front of who another resident stands with not less number of dollars. Note that the people of Berland are people of honor and they agree to swap places only in the manner described above.

输入

The first line contains integer n (1 ≤ n ≤ 200 000) — the number of residents who stand in the line.

The second line contains n space-separated integers ai (0 ≤ ai ≤ 109), where ai is the number of Berland dollars of a man standing on the i-th position in the line. The positions are numbered starting from the end of the line.

输出

If it is impossible to make all the residents happy, print  ":(" without the quotes. Otherwise, print in the single line n space-separated integers, the i-th of them must be equal to the number of money of the person on position i in the new line. If there are multiple answers, print any of them.

输入示例

2
11 8

输出示例

9 10

数据规模及约定

见“输入

题解

考虑每个人在这个队列中的每个位置时的钱数,那么对于原队列第 i 个人,当他跑到队列的 j 位置时,他的钱数变成 ai - j + i。现在我们从最后一个位置开始考虑,我们找到所有人到这个位置时最大的钱数(若有多个最大钱数相等,任取一个),把它作为答案序列的最后一个元素,然后再往前移动,以此类推。我们观察从位置 i 转移到位置 i-1,所有人在当前位置的钱数会加 1,所以他们的相对大小关系是不会改变的。

按照 ai - n + i 从大到小排序,从位置 n 开始处理,每次选择一个最大的作为当前位置的答案,然后整个序列加 1,当前位置左移 1 位。注意判断 小于 0 和 前面的数小于后面的数 这两种不合法的情况。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

int read() {
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
	return x * f;
}

#define maxn 200010
int n, B[maxn];
priority_queue <int> Q;

int main() {
	n = read();
	for(int i = 1; i <= n; i++) Q.push(read() - n + i);
	
	for(int i = n; i; i--) {
		B[i] = Q.top() + n - i; Q.pop();
		if((i < n && B[i] > B[i+1]) || B[i] < 0) return puts(":("), 0;
	}
	
	for(int i = 1; i < n; i++) printf("%d ", B[i]); printf("%d\n", B[n]);
	
	return 0;
}

 

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/5810516.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值