csp信奥赛C++高频考点专项训练之字符串 --【字符串排序】:[NOIP 1998 提高组] 拼数

csp信奥赛C++高频考点专项训练之字符串 --【字符串排序】:NOIP 1998 提高组 拼数

题目描述

设有 n n n 个正整数 a 1 ... a n a_1 \dots a_n a1...an,请将它们连接成一排,相邻数字首尾相接,组成一个最大的整数。

输入格式

第一行有一个整数,表示数字个数 n n n。

第二行有 n n n 个整数,表示给出的 n n n 个整数 a i a_i ai。

输出格式

一个正整数,表示最大的整数。

输入输出样例 1
输入 1
复制代码
3
13 312 343
输出 1
复制代码
34331213
输入输出样例 2
输入 2
复制代码
4
7 13 4 246
输出 2
复制代码
7424613
说明/提示

对于全部的测试点,保证 1 ≤ n ≤ 20 1 \leq n \leq 20 1≤n≤20, 1 ≤ a i ≤ 10 9 1 \leq a_i \leq 10^9 1≤ai≤109。

思路分析

题目要求将给定的 (n) 个正整数拼接成一个最大的整数。
核心思路 :不能简单地按数值大小排序,因为例如 1331213312 小,但 13312 却小于 31213

正确的比较方法是:对于两个字符串 (a) 和 (b),若 (a+b > b+a),则 (a) 应排在 (b) 前面。
具体步骤

  1. 将每个整数转换为字符串,存入数组。
  2. 使用自定义排序规则:比较两个字符串拼接后的大小。
  3. 排序后按顺序拼接所有字符串,输出结果。

复杂度 :排序复杂度 O ( n log ⁡ n ⋅ L ) O(n \log n \cdot L) O(nlogn⋅L),其中 (L) 为字符串平均长度, n ≤ 20 n \leq 20 n≤20 时完全可行。


代码实现

cpp 复制代码
#include <bits/stdc++.h> 
using namespace std;

// 自定义比较函数:若 a+b > b+a,则 a 排在 b 前面
bool cmp(string a, string b) {
    return a + b > b + a;   // 字符串拼接后按字典序比较(数字串长度相同时等价于数值比较)
}

int main() {
    int n; // 数字个数
    cin >> n;
    vector<string> a(n); // 存储数字的字符串形式
    for (int i = 0; i < n; i++) {
        cin >> a[i];   // 直接以字符串读入
    }
    sort(a.begin(), a.end(), cmp);   // 按自定义规则排序
    string ans;   // 存储最终结果
    for (string s : a) {
        ans += s; // 拼接
    }
    cout << ans << '\n'; // 输出最大整数
    return 0;
}

功能分析

  1. 读入数据:从标准输入读取 n 和 n 个正整数(以字符串形式存储,避免溢出)。
  2. 排序 :使用 sort 配合自定义比较函数 cmp,将字符串按"拼接后数值更大"的规则降序排列。
  3. 拼接输出:将排序后的字符串依次连接,得到最大整数并输出。
  4. 正确性:排序规则满足传递性(可证明),能保证最终拼接结果最大;直接拼接字符串避免了整数溢出问题。
  5. 边界处理:输入均为正整数,不存在前导零,输出直接拼接即可。

【完整系列请查看专栏】:
信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转


各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++提高组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
码匠许师傅6 分钟前
【C++ 面试真题】32. 聊聊 C++ 的原子变量与无锁编程
java·c++·面试
wabs66616 分钟前
关于栈【力扣150.逆波兰表达式求值的思考】
数据结构·c++·算法·leetcode··代码随想录
欧特克_Glodon24 分钟前
OpenCV计算机视觉开发入门与实践<十七>:点运算与灰度变换概述
c++·人工智能·opencv·计算机视觉
牛油果子哥q28 分钟前
C++序列式容器深度精讲:vector/list/deque底层实现、扩容原理、迭代器失效、性能对比、工程选型避坑
开发语言·c++·list
啦啦啦啦啦zzzz34 分钟前
升序链表的定时器
linux·服务器·网络·数据结构·c++·链表
WBluuue34 分钟前
数据结构与算法:带权并查集
数据结构·c++·算法
渡我白衣41 分钟前
Acceptor模块的设计与实现
java·linux·服务器·开发语言·网络·c++·人工智能
程序员AlbertTu1 小时前
M01 | 浮点数与误差:数值计算的世界观
c++·数值运算
沫璃染墨1 小时前
《从零入门Linux系统篇(二十八):文件篇·一——Linux为什么“万物皆文件”:从C语言文件流到系统调用》
linux·运维·服务器·开发语言·c++·文件
j7~2 小时前
【C++】《C++STL 笔记:搞懂序列 / 关联容器,聊聊 set 和 map》
c++·set·map·multimap·multiset·键值对pair·序列是容器和关联式容器