Codeforces Global Round 9 参与排名人数10372
[codeforces 1375D] Replace by MEX 根据MEX设置a[i]=i(算法涉及桶排序+构造)
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1375/problem/D
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
D - Replace by MEX | GNU C++17 | Accepted | 31 ms | 3900 KB |
题目大意:给定包含n个元素的数组a,每次通过MEX运算获得的值,可以用来替换a中的一个元素,通过不超过2n的操作,可以获得一个递增的数组b,输出操作次数,以及每次替换的a的元素的位置。
样例模拟如下
Input:
9
8 4 7 6 1 2 3 0 5
Output:
11
9 5 1 8 2 4 6 2 3 7 3
目标将8 4 7 6 1 2 3 0 5变成1 2 3 4 5 6 7 8 9
第一次:
MEX(a)=9
位置1 2 3 4 5 6 7 8 9
数值8 4 7 6 1 2 3 0 5
更新 9
第二次:
MEX(a)=5
位置1 2 3 4 5 6 7 8 9
数值8 4 7 6 1 2 3 0 9
更新 5
第三次:
MEX(a)=1
位置1 2 3 4 5 6 7 8 9
数值8 4 7 6 5 2 3 0 9
更新1
第四次:
MEX(a)=8
位置1 2 3 4 5 6 7 8 9
数值1 4 7 6 5 2 3 0 9
更新 8
第五次:
MEX(a)=0
位置1 2 3 4 5 6 7 8 9
数值1 4 7 6 5 2 3 8 9
更新 0
第六次:
MEX(a)=4
位置1 2 3 4 5 6 7 8 9
数值1 0 7 6 5 2 3 8 9
更新 4
第七次:
MEX(a)=6
位置1 2 3 4 5 6 7 8 9
数值1 0 7 4 5 2 3 8 9
更新 6
第八次:
MEX(a)=2
位置1 2 3 4 5 6 7 8 9
数值1 0 7 4 5 6 3 8 9
更新 2
第九次:
MEX(a)=0
位置1 2 3 4 5 6 7 8 9
数值1 2 7 4 5 6 3 8 9
更新 0
第十次:
MEX(a)=7
位置1 2 3 4 5 6 7 8 9
数值1 2 0 4 5 6 3 8 9
更新 7
第十一次:
MEX(a)=3
位置1 2 3 4 5 6 7 8 9
数值1 2 0 4 5 6 7 8 9
更新 3
全部更新完毕。
根据上述模拟过程,进行编码,获得AC代码如下:
#include <stdio.h>
#define maxn 1010
int cnt[maxn],a[maxn],ans[maxn<<1],k;
void change(int pos,int val){
cnt[a[pos]]--;//原值a[pos]消失
cnt[val]++;//新值val呈现
a[pos]=val;
}
int main(){
int t,n,i,tot,j;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
for(i=1;i<=n;i++)cnt[i]=0;
for(i=1;i<=n;i++)scanf("%d",&a[i]),cnt[a[i]]++;//桶排序
tot=0,k=0;
for(i=1;i<=n;i++)
if(a[i]==i)tot++;//统计a[i]==i的元素数量
if(tot==n){printf("0\n\n");continue;}//特判,本就是1 2 3 4 ...... n形式,无需操作
while(1){
for(i=0;i<=n;i++)
if(!cnt[i])break;//mex
if(i==0){
for(j=1;j<=n;j++)
if(a[j]!=j)break;
k++,ans[k]=j,change(j,0);//把值0安放在j位置
}else{
k++,ans[k]=i,change(i,i),tot++;//把值i安放在i位置
if(tot==n)break;//元素全部设置成功。
}
}
printf("%d\n",k);
for(i=1;i<=k;i++)printf("%d ",ans[i]);
printf("\n");
}
return 0;
}