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] << " "; }
}
}
该代码未对时间复杂度和空间复杂度进行有话,如果有更好的想法和思路的欢迎评论或者发送邮件至我的邮箱22494749@qq.com