【題目鏈接】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]