maxium array
题意
给定一个 a 序列,当 a 非空时可以选择从 a 中切出前 k 个数字(有才行),这 k 个数字取一个最小的且不存在于该非负序列中的数字,得出来的结果加给 b 序列,要求构造出的 b 序列满足字典序尽可能大
样例:
2 2 3 4 0 1 2 0
要让字典序尽可能大,在第6位后面截一下,它之前的数字全都有,所以我们得到5,后面两位得到1.故答案是5 1
0 0 2 1 1 1 0 0 1 1
同理,返回3 2 2 0
思路:
要让字典序尽可能大,所以我们要让每一位的数字尽可能的大,且让数位尽可能多,可以贪心,同时数组应该尽可能全部用完。
标记一个cnt记录数字出现的次数,顺序遍历时,每次不断更新当前已经出现过的数,直到更新结果无法保持连续时,那么空出来的那个数字就是我们应该要填的了。
另外,如果发现某一个数字在当前是空缺却它之后不会再出现的话,那我们当然应该直接把它加入答案。把它留到后面并不会对我们有什么好处。
细节见代码;
#includeusing namespace std; #define ll long long ll t; ll n; ll cnt[200010];//记录每个数出现的次数 ll mas[200010]; ll vis[200010];//标记是否在当前已经被记录 int main() { cin>>t; while(t--){ memset(vis,0,sizeof vis); memset(mas,0,sizeof vis); memset(cnt,0,sizeof cnt); cin>>n; ll ans[200010]; for(int i=1;i<=n;++i){ cin>>mas[i]; cnt[mas[i]]++; } ll bu=0;//记录需要补的数字 ll num=0; for(int i=1;i<=n;++i){ vis[mas[i]]=1;//表示当前这个数已经出现 while(vis[bu]) bu++; cnt[mas[i]]--;//此时代表再次之后mas【i】出现的次数 if(!cnt[bu])//之后不再有这个需要补的数字,所以这里选择直接把它加入答案 { ans[++num]=bu; for(int k=0;k



