80 lines
2.3 KiB
C++
80 lines
2.3 KiB
C++
#include <bits/stdc++.h>
|
||
using namespace std;
|
||
|
||
const int N = 10010; // 最大数字位数
|
||
int n, k; // n:车牌号长度,k:需要修改的数字个数
|
||
int a[N]; // 存储原始数字
|
||
int mi = 0x3f3f3f3f; // 存储最小花费,初始化为极大值
|
||
string res; // 存储最优解的车牌号
|
||
|
||
// 结构体用于存储每个数字的信息
|
||
struct Node {
|
||
int idx; // 数字在原车牌中的位置
|
||
int num; // 原始数字
|
||
int dist; // 与目标数字的距离
|
||
} b[N];
|
||
|
||
int x; // 当前枚举的目标数字
|
||
|
||
// 自定义比较函数,用于排序
|
||
bool cmp(Node &a, Node &b) {
|
||
// 优先按距离排序,距离小的排在前面
|
||
if (a.dist != b.dist)
|
||
return a.dist < b.dist;
|
||
|
||
// 距离相同时,处理策略:
|
||
// 如果原数字大于目标数字,选择索引小的优先修改(保证字典序小)
|
||
// 如果原数字小于目标数字,选择索引大的优先修改(保证字典序小)
|
||
if (a.num > x)
|
||
return a.idx < b.idx;
|
||
else
|
||
return a.idx > b.idx;
|
||
}
|
||
|
||
int main() {
|
||
// 输入处理
|
||
cin >> n >> k;
|
||
string s;
|
||
cin >> s;
|
||
|
||
// 将字符串转换为数字数组
|
||
for (int i = 0; i < n; i++)
|
||
a[i] = s[i] - '0';
|
||
|
||
res = s; // 初始化最优解
|
||
|
||
// 枚举所有可能的目标数字(0-9)
|
||
for (x = 0; x <= 9; x++) {
|
||
// 计算每个数字与目标数字的距离
|
||
for (int i = 0; i < n; i++)
|
||
b[i] = {i, a[i], abs(a[i] - x)};
|
||
|
||
// 按照自定义规则排序
|
||
sort(b, b + n, cmp);
|
||
|
||
// 计算修改前k个数字的总花费
|
||
int cost = 0;
|
||
for (int i = 0; i < k; i++)
|
||
cost += b[i].dist;
|
||
|
||
// 生成临时修改后的车牌号
|
||
string temp = s;
|
||
for (int i = 0; i < k; i++)
|
||
temp[b[i].idx] = x + '0';
|
||
|
||
// 更新最优解
|
||
if (cost < mi) { // 找到更小花费的方案
|
||
mi = cost;
|
||
res = temp;
|
||
} else if (cost == mi) { // 花费相同,选择字典序更小的
|
||
if (temp < res)
|
||
res = temp;
|
||
}
|
||
}
|
||
|
||
// 输出结果
|
||
cout << mi << endl; // 输出最小花费
|
||
cout << res << endl; // 输出最优车牌号
|
||
|
||
return 0;
|
||
} |