找回密码
 立即注册
查看: 38|回复: 0

2024年蓝桥杯国赛B组最小字符串(洛谷P10910):贪心算法构造最小字符串

[复制链接]
  • 打卡等级:即来则安
  • 打卡总天数:28
  • 打卡月天数:2
  • 打卡总奖励:194
  • 最近打卡:2025-08-15 15:43:34

36

主题

2

回帖

2544

积分

VIP会员

积分
2544
发表于 2025-7-20 11:40:44 | 显示全部楼层 |阅读模式
一、问题描述

给定一个长度为N的字符串S和M个待插入字符,要求将这些字符全部插入到S中,使得最终形成的字符串字典序最小。

二、完整代码解析(含详细注释)
  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>
  4. using namespace std;

  5. int main() {
  6.     int N, M;
  7.     string S, chars;
  8.    
  9.     // 读取输入
  10.     cin >> N >> M;
  11.     cin >> S;
  12.     cin >> chars;
  13.    
  14.     // 将待插入字符排序,方便贪心选择
  15.     sort(chars.begin(), chars.end());
  16.    
  17.     string result;
  18.     int charIndex = 0;
  19.    
  20.     // 贪心策略:在能保持字典序最小的位置插入当前最小字符
  21.     for (int i = 0; i < N; ++i) {
  22.         // 当还有字符可插入,且当前字符比待插入字符大时
  23.         while (charIndex < M && chars[charIndex] < S[i]) {
  24.             result.push_back(chars[charIndex]);
  25.             charIndex++;
  26.         }
  27.         result.push_back(S[i]);
  28.     }
  29.    
  30.     // 插入剩余字符
  31.     while (charIndex < M) {
  32.         result.push_back(chars[charIndex]);
  33.         charIndex++;
  34.     }
  35.    
  36.     cout << result << endl;
  37.     return 0;
  38. }
复制代码






三、算法核心思想
  • ‌预处理阶段‌:


    • 对待插入字符排序(O(MlogM)时间)
    • 确保每次都能取到当前最小的可用字符

  • ‌贪心策略‌:


    • 遍历原字符串时,只要当前待插入字符比原字符小就立即插入
    • 这种局部**选择能保证全局**解

  • ‌边界处理‌:


    • **需要检查是否还有未插入的字符
    • 这些字符直接追加到结果字符串末尾

四、常见问题解答

Q:为什么需要先排序待插入字符?
A:排序后可以确保每次都能取出当前最小的可用字符,这是贪心策略的关键

Q:如何处理多个相同最小字符的情况?
A:排序后相同字符会相邻,算**按顺序使用它们

Q:为什么**要单独处理剩余字符?
A:可能存在所有待插入字符都比原字符串字符小的情况


来源:编程学习







您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表