【中石油OJ-5140】 Escape Room

题目描述

As you know, escape rooms became very popular since they allow you to play the role of a video game hero. One such room has the following quiz. You know that the locker password is a permutation of N numbers. A permutation of length N is a sequence of distinct positive integers, whose values are at most N. You got the following hint regarding the password - the length of the longest increasing subsequence starting at position i equals Ai. Therefore you want to find the password using these values. As there can be several possible permutations you want to find the lexicographically smallest one. Permutation P is lexicographically smaller than permutation Q if there is an index i such that Pi < Qi and Pj = Qj for all j < i. It is guaranteed that there is at least one possible permutation satisfying the above constraints. 
Can you open the door?

输入

The first line of the input contains one integer N (1≤N≤105).
The next line contains N space-separated integer Ai (1≤Ai≤N).
It’s guaranteed that at least one possible permutation exists.

输出

Print in one line the lexicographically smallest permutation that satisfies all the conditions.

样例输入

4

1 2 2 1

样例输出

4 2 3 1

题意:有1~N这几个数字,要求按顺序排列,给定一个数组,每个数组代表当前位置这个数字可以和后面的数字组成的最长上升序列,要求必须字典序输出

       这道题也很简单,首先,排自己是最大的数(即ai=1的数)比如题中的就是第一位和第四位,当前可以使用的是4321,那么把4和3按顺序放入。

      为什么这么做呢,因为我们知道,想让他是1,那么必须是当前可用的最大的数,如果4在后面,那么在第一位的数一定可以和他组成一个上升序列,这个位置就不是1了,由此可见不能往后放;如果放在前面,那么字典序一定比现在的情况大,所也也不可取。

        而之所以从1开始放,是为了每次找到的都是当前最大的数字可以放置的字典序最小位置。因为我们知道,大数一定是越往后越好,而每个1前面肯定有2,2前面也肯定有3,这样才是一个完整的序列,所以我们从ai=1的位置开始一直放到ai最大的位置,就可以得到符合题意的序列了。

另:用vector存比较省内存。

代码:

#include<stdio.h>
#include<vector>
using namespace std;
int duo[100005];
int jie[100005];
vector<int>shou[100005];
int main(){
    int n;
    scanf("%d",&n);
    int ru=0;
    for(int i=1;i<=n;i++){
        scanf("%d",&duo[i]);
        shou[duo[i]].push_back(i);
        if(duo[i]>ru)ru=duo[i];
    }
    int jin=n;
    for(int i=1;i<=ru;i++){
        for(int j=0;j<shou[i].size();j++){
            jie[shou[i][j]]=jin;jin--;
        }
    }
    for(int i=1;i<=n;i++){
        if(i==1)printf("%d",jie[i]);
        else printf(" %d",jie[i]);
    }
    puts("");
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值