题面
【问题描述】
爸爸带着小S来到了JZ广场,小S发现广场的一边从左到右有一排高度不同的柱子,十分壮观。爸爸告诉小S,这里一共有N根柱子,每根柱子的高度都是1至N之间的整数,而且任意两根柱子不一样高。
小S刚学会了数数和比较两个整数的大小,于是她想利用这个机会来展示一下J。她找出一张纸,依次写下了N个数,其中第i个数表示从左起第i根柱子的左边比它高的柱子的根数。例如,如果柱子的排列是3,1,2,那么小S就会记下0,1,1。
现在小S想考考你,她把那张纸给你,你能知道柱子是怎样排列的吗?
【输入格式】
第一行包含一个整数 \(N\)(\(1\le N\le 30000\)),表示柱子的根数。
接下来的 \(N\) 行,每行一个整数。第 \(i+1\) 行表示纸上的第 \(i\) 个数。
【输出格式】
第一行是 YES
或者 NO
,表示小S是否数对了。
如果第一行是 YES
,则下面输出 \(N\) 行,每行一个整数。第 \(i+1\) 行表示从左起第 \(i\) 根柱子的高度。
【样例输入 1】
7
0
0
1
0
2
0
4
【样例输出 1】
YES
1
5
2
6
4
7
3
【样例输入 2】
3
0
2
0
【样例输出 2】
NO
解
不难发现,这相当于求排名为 \(a_i\) 的数,并将它删去。我们用一个 std::vector
维护没有用过的高度,那么每次可以求出这个数并删去。
程序
#define MAXN 30050
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n;
int a[MAXN], r[MAXN];
vector<int> ch;
void fail() {
cout << "NO" << endl;
exit(0);
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
ch.push_back(i + 1);
}
for (int i = n - 1; i > -1; i--) {
int ind = ch.size() - a[i] - 1;
// cout << "ind " << ind << ", size " << ch.size() << ", no. " << a[i] << endl;
// for (int j = 0; j < ch.size(); j++) cout << ch[j] << " "; cout << endl;
if (ind < 0 || ind >= ch.size()) fail();
r[i] = ch[ind];
if (r[i] < 1) fail();
// bitadd(r[i], 1);
ch.erase(ch.begin() + ind); // error?
}
cout << "YES" << endl;
for (int i = 0; i < n ; i++) {
cout << r[i] << endl;
}
return 0;
}