CR658 题解

比赛入口

vp 的时候只会 A1A2B,我就这?

C. Mastermind

题意:给定一个长度为 \(n\) 的序列 \(b\),值域 \([1,n+1]\) ,要求还原序列 \(a\) ,使得对齐的元素有 \(x\) 个,共同的元素有 \(y\) 个。

显然一些元素最大错排为 \(n-2\max(0,Mx-n/2)\),于是我们要让 \(Mx\) 尽量小,于是选 \(x\) 个时选出现次数最大的。

然后 \(y\) 个时循环位移 \(Mx\) 位即可,剩下的用一个莫名其妙的颜色填好就行了。这么简单的题,然而我考场上不会。

#include<bits/stdc++.h>
using namespace std;
#define inf 1e9
const int maxn=2e5+10;
const int mod=1e9+7;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
	return x*f;
}
int T,n,m,mx,cz,b[maxn],cx,cy,a[maxn],c[maxn];
vector<int>pos[maxn];
#define pb push_back
#define pii pair<int,int>
#define fi first
#define se second
#define mkp make_pair
priority_queue<pii>q;
int main(){
	T=read();
	while(T--){
		n=read(),cx=read(),cy=read();
		for(int i=1;i<=n;i++)b[i]=read(),pos[b[i]].pb(i);
		int ept=0;for(int i=1;i<=n+1;i++)if(!pos[i].size())ept=i;
		for(int i=1;i<=n;i++)a[i]=ept;
		for(int i=1;i<=n+1;i++)if(pos[i].size())q.push(mkp((int)pos[i].size(),i));
		for(int i=1;i<=cx;i++){
			pii x=q.top();q.pop();a[pos[x.se].back()]=x.se;
			x.fi--;pos[x.se].pop_back();if(x.fi)q.push(x);
		}m=mx=cz=0;
		for(int i=1;i<=n+1;i++){
			mx=max(mx,(int)pos[i].size());
			while(pos[i].size())c[++m]=pos[i].back(),pos[i].pop_back();
		}
		for(int i=1,j=mx+1;i<=m;i++){
			j=(j-1)%m+1;if(cz==cy-cx)break;
			if(b[c[i]]!=b[c[j]])
				a[c[i]]=b[c[j]],j=j%m+1,cz++;
		}
		if(cz==cy-cx){
			puts("YES");
			for(int i=1;i<=n;i++)
				printf("%d ",a[i]);puts("");
		}else puts("NO");
		while(!q.empty())q.pop();
		for(int i=1;i<=n+1;i++)pos[i].clear();
	}
    return 0;
}

D. The Majestic Brown Tree Snake

什么时候有闲情雅致再说吧。

E. Origami

计几!以后计几的时候再说吧。

posted @ 2022-01-16 20:39  syzf2222  阅读(74)  评论(0编辑  收藏  举报