(1)思路:以0到9为最佳数字n,循环10次,每次循环中寻找当数字为n时达到K个数字相同时的最小代价(首先是代价,其次才是字典序);
(2)算法:从数字n开始向外扩散,采用贪心算法思想(代价为先),首先寻找相同的数字,然后寻找比该数字大1与小1的数字,然后是大2与小2的的数字,以此类推,直到到达K个相同或者到达边界;
(3)注释:代码未优化,只是基本实现了思想,如有不足欢迎指正。

#include <iostream>
#include <map>
#include <string>
using namespace std;

int main()
{
    double N, K;
    string phoneNumber;
    while (cin >> N >> K >> phoneNumber)
    {
        //1.初始化阶段,用于定义各类数值与原始数据存储

        //1.1 存储初始值
        string phoneNumber_back = phoneNumber;
        double K_back = K;
        //1.2 用于存储数据,利用map的自带排序可以轻松输出最小代价的结果
        map<int, string> save;
        //1.3 各种计数
        int sameNum2CurrentNum = 0;      //存储与当前num相同的数据数
        int currentValue = 0;
        //1.4 用于存储最优解是否已经被找到
        bool isBestResultFind = false;

        //2.大循环,实现0-9的全部查找
        for (int currentNum = 0; currentNum <= 9; currentNum++)
        {
            //2.1 如果最优解已经被找到,直接跳出循环,执行第3步输出结果
            if (isBestResultFind)
                break;

            //2.2 先遍历所有数值,如果相同数目已经超过了K,则将最优值赋值给save后跳出;
            for (int i = 0; i < N; i++)
            {
                if (phoneNumber[i] - '0' == currentNum)
                    sameNum2CurrentNum++;
            }
            if (sameNum2CurrentNum >= K)
            {
                save.insert({ 0,phoneNumber });
                isBestResultFind = true;
                break;
            }

            //2.3 如果2.2未满足,则根据sameNum2CurrentNum将K减小,并定义贪心算法的两个变量
            int maxcurrentNum = currentNum;        //currentNum向上扩张的数
            int mincurrentNum = currentNum;        //currentNum向下扩张的数
            K = K - sameNum2CurrentNum;

            //2.4 贪心算法实现,currentNum同时向上下匀速扩张1,上下边界为9和0。当边界都达到,或者K被使用完后,跳出循环
            while ( K || (maxcurrentNum > 9 && mincurrentNum < 0))
            {
                if (!K)
                    break;

                maxcurrentNum++;
                mincurrentNum--;
                //2.4.1 先从最大位数向最小位数查找能替换的值
                if (maxcurrentNum <= 9)
                {
                    for (int i = 0; i < N; i++)
                    {
                        if (!K)
                            break;
                        if (phoneNumber[i] - '0' == maxcurrentNum)
                        {
                            currentValue += phoneNumber[i] - '0' - currentNum;
                            phoneNumber[i] = currentNum + '0';
                            K--;
                        }
                    }
                }
                //2.4.2 然后再从最小位数向最大位数查找能替换的值(2.4.1与2.4.2的先后顺序是为了保证字典序最小)
                if (mincurrentNum >= 0)
                {
                    for (int i = N - 1; i >= 0; i--)
                    {
                        if (!K)
                            break;
                        if (phoneNumber[i] - '0' == mincurrentNum)
                        {
                            currentValue += currentNum - (phoneNumber[i] - '0');
                            phoneNumber[i] = currentNum + '0';
                            K--;
                        }
                    }
                }
            }

            //2.5 当贪心算法流程结束后,进行数据的存储,与数据的还原工作。
            save.insert({ currentValue, phoneNumber });
            phoneNumber = phoneNumber_back;
            K = K_back;
            sameNum2CurrentNum = 0;
            currentValue = 0;
        }
        //3.所有循环完成,或者最优解被查找出来后,输出结果
        cout << save.begin()->first << endl;
        cout << save.begin()->second << endl;
        save.clear();    
    }
    return 0;
}