[codeforces 1375D] Replace by MEX 根据MEX设置a[i]=i(算法涉及桶排序+构造)

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

ProblemLangVerdictTimeMemory
D - Replace by MEX GNU C++17Accepted31 ms3900 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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值