一个车牌号由n位数字组成。如果一个车牌至少有k位数字是相同的,那么我们就说这个车牌漂亮的车牌。现在华沙想要改变他自己的车牌,使得他的车牌变得漂亮。当然,改车牌是要花钱的。每改变一位数字所要花费的费用等于当前位上的新旧数字之差的绝对值。那么总费用就是每位上所花费用的总和。
举例如下,
旧牌为0123,新牌为7765,那么对应第一位所花费用为|0-7|=7,第二位为|1-7|=6,第三位为|2-6|=4,第四位为|3-5|=2,总和为7+6+4+2=19
华沙想用最少的钱,使他的车牌变得漂亮起来。现在给定n,k,和旧牌的号码,计算换牌的最少费,以及新牌的号码,
如果最少费用的号码有多个,我们取字典序最小的那个。
样例解释:
在样例中,把第二个数字换成“8”花费|9-8|=1,把第五个数字换成“8”也花了1。
把第六个数字换成“8”花费|6-8|=2.总费用为1+1+2=4,新号码为“888188”
两个长度为n的序列比较方法如下。
存在两个序列x,y,长度都是n。
如果存在i(1≤i≤n)和任意j(1≤j<i)使得 xi<yi 并且 xj=yj ,那么我们就说x比y小。
Input
单组测试数据第一行,两个由空格隔开的数字n和k(2≤n≤10^4,2≤k≤n),表示旧牌的位数,和至少要有k位数字相同才能构成漂亮的车牌。第二行有n位数字,代表华沙的旧车牌。(旧车牌中只有数字)。
Output
共两行,第一行,一个整数,代表换牌的最小费用,第二行,n位数字,表示新的车牌。如果最小费用的车牌有多个,输出字典序最小的那个。
Input示例
6 5898196
Output示例
4888188
#include <bits/stdc++.h>
#define INF 12345678
using namespace std;
const int AX = 1e4+66;
int n , k ;
char s[AX];
int a[AX];
struct Node
{
int v;
int id;
int val;
bool f;
}ans[AX];
bool cmp( const Node &a , const Node &b ){
if( a.v != b.v ) return a.v < b.v;
else if( a.val != b.val ) return a.val > b.val;
else {
if( a.f ) return a.id < b.id;
else return a.id > b.id;
}
}
int main(){
scanf("%d%d",&n,&k);
scanf("%s",s);
int falg = 1 ;
memset(a,0,sizeof(a));
for( int i = 0 ; i < n ; i++ ){
a[s[i]-'0'] ++ ;
if( a[s[i]-'0'] >= k ){
falg = 0;
}
}
if( falg ){
int val;
int coss = -1 ;
char res[AX];
for( int jj = 0 ; jj <= 9 ; jj++ ){
val = jj;
for( int i = 0 ; i < n ; i++ ){
ans[i].v = abs( (s[i]-'0') - val);
ans[i].id = i;
ans[i].val = s[i]-'0';
ans[i].f = ( (s[i]-'0') > val ? true : false );
}
int cost = 0;
sort( ans , ans + n , cmp );
int kk = k - a[val];
for( int i = 0 ; i < n ;i++ ){
if( kk == 0 ) break;
if( s[ans[i].id] == (val+'0') ) continue;
else{
kk--;
cost += ans[i].v;
ans[i].val = val;
}
}
char tmp[AX];
for( int i = 0 ; i < n ; i++ ){
int index = ans[i].id;
tmp[index] = (char)(ans[i].val+'0');
}
if( coss != -1 ){
if( cost < coss ){
coss = cost;
for( int i = 0 ; i < n ; i++ ){
res[i] = tmp[i];
}
}else if( coss == cost ){
if( strcmp( res , tmp ) > 0 ){
for( int i = 0 ; i < n ; i++ ){
res[i] = tmp[i];
}
}
}
}else{
coss = cost;
for( int i = 0 ; i < n ; i++ ){
int index = ans[i].id;
res[index] = (char)(ans[i].val + '0');
}
}
}
cout << coss << endl;
for( int i = 0 ; i < n ; i++ ){
cout << res[i];
}
cout << endl;
}else{
printf("0\n");
printf("%s\n",s);
}
return 0;
}