题解:洛谷 P14357 拼数

【题目来源】

洛谷:P14357 [CSP-J 2025] 拼数 / number(民间数据) - 洛谷

【题目描述】

小 R 正在学习字符串处理。小 X 给了小 R 一个字符串 \(s\),其中 \(s\) 仅包含小写英文字母及数字,且包含至少一个 \(1 \sim 9\) 中的数字。小 X 希望小 R 使用 \(s\) 中的任意多个数字,按任意顺序拼成一个正整数。注意:小 R 可以选择 \(s\) 中相同的数字,但每个数字只能使用一次。例如,若 \(s\)\(\tt 1a01b\),则小 R 可以同时选择第 \(1,3,4\) 个字符,分别为 \(1,0,1\),拼成正整数 \(101\)\(110\);但小 R 不能拼成正整数 \(111\),因为 \(s\) 仅包含两个数字 \(1\)。小 R 想知道,在他所有能拼成的正整数中,最大的是多少。你需要帮助小 R 求出他能拼成的正整数的最大值。

【输入】

输入的第一行包含一个字符串 \(s\),表示小 X 给小 R 的字符串。

【输出】

输出一行一个正整数,表示小 R 能拼成的正整数的最大值。

【输入样例】

5

【输出样例】

5

【核心思想】

  1. 问题分析:给定一个包含小写字母和数字的字符串 \(s\),要求从中选取任意多个数字(每个数字字符只能用一次),按任意顺序拼接成一个最大的正整数。本质上是贪心排序问题:要使拼接后的整数最大,只需将所有可用数字按降序排列输出。

  2. 算法选择

    • 计数排序:统计字符串中每个数字 \(0 \sim 9\) 的出现次数
    • 降序输出:从 \(9\)\(0\) 依次输出每个数字的所有出现
  3. 关键步骤

    • 读取数据:读入字符串 \(s\)
    • 统计数字频次:遍历 \(s\),对每个数字字符 \(c\)\(B[c - '0'] \leftarrow B[c - '0'] + 1\)
    • 降序输出\(i = 9\)\(0\)):
      • \(B[i] > 0\),循环输出 \(i\)\(B[i]\)
    • 输出换行
  4. 时间/空间复杂度

    • 时间复杂度:\(O(|s|)\),线性扫描字符串
    • 空间复杂度:\(O(1)\),固定大小的计数数组
  5. 贪心降序的核心思想

    • 字典序最大化:多位整数的比较从最高位开始,因此将大的数字放在前面总是更优
    • 计数排序的简洁性:数字只有 \(10\) 种,用计数数组 \(O(|s|)\) 完成排序,无需通用排序算法
    • 字母的自动过滤:非数字字符在 s[i] - '0' 时会产生非法索引,但代码中未显式过滤;实际上输入保证至少有一个数字,且字母的 ASCII 值与数字相差较大,在合理范围内不会冲突(但严格来说应加 isdigit 判断)
    • 正整数的隐含约束:输出至少包含一个数字,且前导零问题不存在(因为是从 \(9\)\(0\) 输出,\(0\) 总是在最后)
    • 适用于数字提取、贪心排序、简单构造类问题

【算法标签】

普及- #其他排序

【代码详解】

#include <bits/stdc++.h>
using namespace std;

string s;        // 存储输入的数字字符串
int B[15];       // 计数数组,记录每个数字(0-9)出现的次数

int main()
{
    // 输入数字字符串
    cin >> s;

    // 统计每个数字出现的次数
    for (int i = 0; i < s.size(); i++)
    {
        // 将字符转换为数字索引,并增加对应计数
        B[s[i] - '0']++;
    }

    // 从大到小输出数字(9到0)
    for (int i = 9; i >= 0; i--)
    {
        // 如果当前数字出现过
        if (B[i] != 0)
        {
            // 输出该数字的所有出现次数
            while (B[i] > 0)
            {
                cout << i;  // 输出当前数字
                B[i]--;     // 减少计数
            }
        }
    }

    // 输出换行符
    cout << endl;

    return 0;
}

【运行结果】

5
5

【算法真传】

从一道CSP-J真题出发:聊聊贪心排序与计数排序

posted @ 2026-08-17 09:45  团爸讲算法  阅读(24)  评论(0)    收藏  举报