'commit'
This commit is contained in:
80
TangDou/CSP-J/AcWingTraining/MaiChePai_1.cpp
Normal file
80
TangDou/CSP-J/AcWingTraining/MaiChePai_1.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user