Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) B - Box

【题目链接】B题链接

【题目类型】 模拟

【题目大意】给你一段长度为n的序列,q1,q2,q3,q4…qn 这段序列是通过p1,p2…pn, 在p1, p2…pn当中只存在1到n的数字,且不会出现重复现象,经过如下操作获得的
q1=p1,
q2=max(p1,p2),
q3=max(p1,p2,p3),

qn=max(p1,p2,…,pn).
现在请求你求解p1,p2…pn(该p序列可能存在多种情况,求解任意一种即可)

【解题思路】首先我们可以先对第一个样例进行一下分析,因为题目给出了样例1的求解过程
input
5
1 3 4 5 5
q1=p1=1;
q2=max(p1,p2)=3;
q3=max(p1,p2,p3)=4;
q4=max(p1,p2,p3,p4)=5;
q5=max(p1,p2,p3,p4,p5)=5.
可以求解出

  • p1 = 1
  • 因为max(p1,p2)=3;所以p2 = 3
  • 因为max(p1,p2,p3)=4所以p3 = 4
  • 因为max(p1, p2, p3, p4)=5 所以p4 = 5
  • 因为max(p1,p2,p3,p4,p5)=5而p4 = 5,而只有2没有在序列中出现过,所以p5只能是2
    解得
    output
    1 3 4 5 2
    (这是解答出来的情况,题目也有说到是存在解答不出来的情况的,所以在看下输出为-1的数据是什么样的
    input
    4
    1 1 3 4
    很明显这种数据是会出现p1和p2都是1的情况,那么就不满足序列数字不重复的条件了所以输出了-1

通过以上数据就能很明显的知道了,越大的数据需要越早出现(我表达可能不是太好,但请尽量理解这一句话的意思)
就比如
5
3 3 5 5 5
那么我的序列可以是
3 2 5 4 1,因为我的后面三个都是5,我要保证经过max得到的值是5,所以就需要这么排列

ans是我的答案数组,is
(1)要保证出现的数字是不重复的,我声明了一个set变量用于筛去已经出现在答案数组的数字
(2)我的q数组就是题目中所说的q数组,用于接收输入的数据
(3)如果我的q[i] > p[i] 的那我直接吧q[i]放到我的答案数组ans内,并且在我的判断数字是否有出现过的容器set p 的 p 中删除这个q[i]这个值,也就是p.earse(q[i]);
(4)最后把p中剩余的数字放进去ans就可以了,因为我们已经满足了,大的数字尽量往前排了
(5)有wa在3~5case的可以试一试这个样例
5
3 3 5 5 5

/**
 *    This code has been written by YueGuang, feel free to ask me question. Blog: http://www.yx.telstudy.xyz
 *    created:
 */
#include <cstdio>
#include <iostream>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#define rep(i, a, b) for(int i = a; i < b; i++)
#define rep_(i, a, b) for(int i = a; i <= b; i++)
#define rep(i, n) for(int i = 0; i < n; i++)
#define rep1(i, n) for(int i = 1; i < n; i++)
#define rep_(i, n) for(int i = 0; i <= n; i++)
#define rep1_(i, n) for(int i = 1; i <= n; i++)
#define pb(x) push_back(x);
#define si(x) scanf("%d", &x);
#define sl(n) scanf("%lld", &n);
#define si(n) scanf("%d", &n);
#define RepAll(a) for(auto x: a)
#define cout(ans) cout << ans << endl;
typedef long long ll;

using namespace std;
const int maxn = 1e5+50;
set<int> p;
int q[maxn], ans[maxn];
int main(){
    int t; si(t);
    while(t--){
        bool isflag = true;
        int n; si(n);
        rep1_(i, n){ si(q[i]);}
        p.clear();
        rep1_(i, n){ p.insert(i); }
        rep1_(i, n){
            if(q[i] < q[i - 1]){ isflag = false; break;}
            if(q[i] > q[i - 1]){ ans[i] = q[i]; p.erase(q[i]);}
            else{
                if ((*p.begin()) < q[i]){
                    ans[i] = (*p.begin());
                    p.erase(*p.begin());
                }
                else{
                //如果set中剩余的数字比q[i]还大的话,那很明显是错的,max最后的值就会不符合要求
                    isflag = false;
                    break;
                }
            }
        }
        if(isflag == false){printf("-1\n"); continue;}
        rep1_(i, n){cout << ans[i] << " "; }
    }
}

该代码未对时间复杂度和空间复杂度进行有话,如果有更好的想法和思路的欢迎评论或者发送邮件至我的邮箱[email protected]

发布了20 篇原创文章 · 获赞 3 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43382350/article/details/103229216