友诸葛亮

题目链接: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]<<' ';
	}
}
posted @ 2025-04-14 19:31  Marinaco  阅读(27)  评论(0)    收藏  举报
//雪花飘落效果