友诸葛亮
题目链接:https://ac.nowcoder.com/acm/contest/106859/E
题意:
给出x个1,y个2,z个3的排列,重新排序使得新的排列尽量少地匹配旧的排列
思路:
把x,y,z和它们分别代表的数字编号排序,设个数从大到小为:c,b,a。分别代表nc,nb,na的数字
1.c>=a+b
显然将nc安排在na和nb的位置,将na和nb安排在nc的位置最优,如果nc的位置还有剩余,那么只能填入nc
2.c<a+b
此时可以排序使得数字完全不自匹配
一种方法是:nb位置放入b个nc,na位置放入(c-b)个nc,(a-(c-b))个nb,nc位置放入a个na,(c-a)个nb
按上面两种情况分类讨论即可
void solve(){
int x,y,z;cin>>x>>y>>z;
int n=x+y+z;
vector<int>arr(n+1);
rep(i,1,n){
cin>>arr[i];
}
pii at[3];
at[0].fi=x;at[1].fi=y;at[2].fi=z;
at[0].se=1;at[1].se=2;at[2].se=3;
sort(at,at+3);
int a=at[0].fi,b=at[1].fi,c=at[2].fi;
int na=at[0].se,nb=at[1].se,nc=at[2].se;
vector<int>ans(n+1);
if(c>=a+b){
int cnt_a=0,cnt_b=0;
rep(i,1,n){
if(arr[i]==na||arr[i]==nb){
ans[i]=nc;
}else {
if(cnt_a!=a){
cnt_a++;ans[i]=na;
}else if(cnt_b!=b){
cnt_b++;ans[i]=nb;
}else{
ans[i]=nc;
}
}
}
}else if(c<a+b){
int cnt_a=0,cnt_b=0,cnt_c=0;
rep(i,1,n){
if(arr[i]==na){
if(cnt_c!=(c-b)){
cnt_c++;ans[i]=nc;
}else{
cnt_b++;ans[i]=nb;
}
}else if(arr[i]==nb){
ans[i]=nc;
}else if(arr[i]==nc){
if(cnt_a!=a){
cnt_a++;ans[i]=na;
}else{
ans[i]=nb;
}
}
}
}
rep(i,1,n){
cout<<ans[i]<<' ';
}
}

浙公网安备 33010602011771号