鱼C论坛

 找回密码
 立即注册
查看: 46|回复: 6

[技术交流] 【CSP-J 2025T1】拼数 详细解析

[复制链接]
发表于 2026-9-21 06:07:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 高山 于 2026-9-24 18:59 编辑

如果你正在复习CSP-J 第二轮

那你可以按照本系列的节奏进行



在本系列中,我们将带领鱼油一同回顾算法基础,完成CSP算法真题,帮助他们尽可能在复赛获得更高的分数。1

话不多说,让我们先看看题目:


                               
登录/注册后可看大图

可使用配套的在线OJ评测本题->


                               
登录/注册后可看大图



                               
登录/注册后可看大图

P14357 [CSP-J 2025] 拼数
小 R 正在学习字符串处理。小 X 给了小 R 一个字符串 s,其中 s 仅包含小写英文字母及数字,且包含至少一个 1~9 中的数字。小 X 希望小 R 使用 s 中的任意多个数字,按任意顺序拼成一个正整数。

注意:小 R 可以选择 s 中相同的数字,但每个数字只能使用一次。
例如,若 s 为 1a01b,则小 R 可以同时选择第 1、3、4 个字符,分别为 1、0、1,拼成正整数 101 或 110;但小 R 不能拼成正整数 111,因为 s 仅包含两个数字 1。
小 R 想知道,在他所有能拼成的正整数中,最大的是多少。你需要帮助小 R 求出他能拼成的正整数的最大值。

【输入格式】
输入的第一行包含一个字符串 s,表示小 X 给小 R 的字符串。

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

【输入输出样例】

输入 #1
  1. 29010
复制代码

输出 #1
  1. 92100
复制代码

【样例 1 说明】
s 包含数字 2、9、0、1、0。可以证明,小 R 拼成的正整数的最大值为 92100。


输入 #2
  1. 1a01b
复制代码

输出 #2
  1. 110
复制代码

【数据范围】

设 |s| 为字符串 s 的长度。对于所有测试数据,保证:

  • 1 ≤ |s| ≤ 1 000 000
  • s 仅包含小写英文字母及数字字符 0~9
  • s 包含至少一个 1~9 中的数字


【特殊性质】

特殊性质 A:字符串 s 中只包含数字字符。
特殊性质 B:字符串 s 中数字字符的个数不超过 1000。
点击目录的「解析」按钮或点击下一页即可查看答案。如您


本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2026-9-21 06:07:56 | 显示全部楼层
鱼油你好,这道题是典型的贪心 + 计数题。核心一句话:把所有数字从大到小拼起来,就是最大正整数。

一、为什么这样贪心?

比较两个正整数:
1. 先比位数,位数多的更大。
2. 位数相同,再比高位,高位大的更大。

所以:
- 能用的数字全用上,0也放末尾,这样位数最多。
- 数字从9到0依次放,保证高位尽量大。
- 字母不能拼数,直接跳过。

例如 29010 中有 2、9、0、1、0,从大到小排就是 92100。

二、实现步骤

1. 开一个 cnt[10] 数组,统计数字 0~9 各出现几次。
2. 遍历字符串,遇到数字字符就 cnt[s[i] - '0']++。
3. 从 9 到 0,把数字 i 重复 cnt[i] 次接到答案后面。
4. 输出答案字符串。

三、完整满分代码


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

  3. int main() {
  4.     ios::sync_with_stdio(false);
  5.     cin.tie(0);

  6.     string s;
  7.     cin >> s;

  8.     int cnt[10] = {0};
  9.     for (char c : s) {
  10.         if (isdigit(c)) {
  11.             cnt[c - '0']++;
  12.         }
  13.     }

  14.     string ans;
  15.     for (int i = 9; i >= 0; i--) {
  16.         ans += string(cnt[i], char('0' + i));
  17.     }

  18.     cout << ans << '\n';
  19.     return 0;
  20. }
复制代码


四、复杂度

时间复杂度:O(|s| + 10)  
空间复杂度:O(1)(不计输出字符串)  
数据范围 |s| ≤ 1 000 000,完全可以通过。

五、易错点

- 字母必须跳过,不能参与拼数。
- s[i] - '0' 是把字符变成数字的关键写法。
- 0 放最后不会产生前导零,因为题目保证至少有一个 1~9 的数字。
- 用 string(cnt[i], '0' + i) 可以快速生成重复字符。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-21 07:35:13 | 显示全部楼层

回帖奖励 +6 鱼币

点了点了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2026-9-21 13:01:40 | 显示全部楼层

回帖奖励 +6 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2026-9-24 11:50:18 | 显示全部楼层

回帖奖励 +6 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2026-9-24 18:51:49 | 显示全部楼层

回帖奖励 +6 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2026-9-24 18:54:25 | 显示全部楼层

回帖奖励 +6 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2026-10-11 00:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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