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
计几!以后计几的时候再说吧。