CodeForces 931C Laboratory Work 水题,构造
*这种题好像不用写题解...
题意:
一个人要改动别人的实验记录,实验记录记录是一个集合
实验记录本身满足:$max(X)-min(X)<=2$
改动结果要求:
1.新的集合平均值和之前的一样
2.新的集合,$max(Y)<=max(X),min(Y)>=min(X)$
求新一个和之前相同数值最少的新记录
题解:
首先考虑不同情况,
如果$max-min<=1$ :因为要保证平均值且值域受限制不变,无法改变值(增加一个值之后,要相应的把另外一值减小,而数值只有2/1种,改动没有意义)
如果$max-min=2$ 我们把所有值分为 $max,mid,min$ 三类那么就有了2种选择:
1.把所有的$mid$两两分组 变成$max,min$
2.把所有的$max,min$两两组合,变成$mid$
我们比较一下谁比较就行了...
1A
#include <bits/stdc++.h> #define ll long long #define rep(ii,a,b) for(int ii=a;ii<=b;ii++) using namespace std; const int maxn=1e5+10; int casn,n,m,k; int num[maxn]; int cnt[3]; int main(){ rep(i,1,n) cin>>num[i]; sort(num+1,num+1+n); rep(i,1,n)cnt[num[i]-num[1]]++; ll ans1=cnt[2]+cnt[0]+cnt[1]%2; ll ans2=max(cnt[2],cnt[0])-min(cnt[2],cnt[0])+cnt[1]; ll ans=min(ans1,ans2); if(num[n]-num[1]<=1) ans=n; else if(ans1<ans2){ cnt[0]+=cnt[1]/2; cnt[2]+=cnt[1]/2; cnt[1]%=2; }else { cnt[1]+=2*min(cnt[0],cnt[2]); if(cnt[2]>cnt[0]) { cnt[2]-=cnt[0]; cnt[0]=0; }else{ cnt[0]-=cnt[2]; cnt[2]=0; } } cout<<ans<<endl; while(cnt[0]--) cout<<num[1]<<' '; while(cnt[1]--) cout<<num[1]+1<<' '; while(cnt[2]--) cout<<num[1]+2<<' '; return 0; }