STL - 柱子的排列(pillar) 2019.8.2

题面

【问题描述】

爸爸带着小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;
}

猜你喜欢

转载自www.cnblogs.com/lrw04/p/11795103.html
STL