水水的题,做了很长时间才出来,还看了两组数据,抠脚了,很皮,
思路是变为k个0,k个1.。。。k个9,变得话从 t左右减相同的这样最小,看哪个最小,输出哪个,还有就是顺序问题,顺序的话如果有相等的数字,比较改变后字符串大小,没有相等的如果把大的数改成小的数从前往后改,小的数改为大的数,从后往前改。。。。。必须要细节。。。
#include <bits\stdc++.h> #include <math.h> using namespace std; char s[10009],s1[10009],s2[10009]; int n,m; int a[15],b[15],c[15]; int main() { scanf("%d%d",&n,&m); scanf("%s",s); memset(a,0,sizeof(a)); for(int i=0;i<n;i++) { a[s[i]-'0']++; } int min1=1e6+7; for(int k=0;k<=9;k++) { int i=k-1,j=k+1; int tmp=m-a[k]; if(tmp<=0) { min1=0; strcpy(s1,s); break; } memset(b,0,sizeof(b)); int ans=0; while(1) { if(i<0&&j>9)break; if(j<=9) { if(tmp>=a[j])tmp-=a[j],ans+=(j-k)*a[j],b[j]=a[j]; else b[j]=tmp,ans+=(j-k)*tmp,tmp=0; } if(i>=0) { if(tmp>=a[i])b[i]=a[i],tmp-=a[i],ans+=(k-i)*a[i]; else b[i]=tmp,ans+=(k-i)*tmp,tmp=0; } i--; j++; } if(min1>=ans) { strcpy(s2,s); memset(c,0,sizeof(c)); for(i=n-1;i>=0;i--) { int p=(s2[i]-'0'); if(c[p]<b[p]&&p<k) {s2[i]=('0'+k); c[p]++; } } for(i=0;i<n;i++) { int p=(s2[i]-'0'); if(c[p]<b[p]&&p>k) {s2[i]=('0'+k); c[p]++; } } if(min1>ans) { min1=ans; strcpy(s1,s2); } else { if(strcmp(s1,s2)>0)strcpy(s1,s2); } } } printf("%d\n",min1); puts(s1); return 0; }