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]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章