【题解】【排序】—— [NOIP1998 提高组] 拼数
[NOIP1998 提高组] 拼数
题目描述
设有 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
3
13 312 343
输出 #1
34331213
输入 #2
4
7 13 4 246
输出 #2
7424613
提示
对于全部的测试点,保证 1 ≤ n ≤ 20 1 \leq n \leq 20 1≤n≤20, 1 ≤ a i ≤ 1 0 9 1 \leq a_i \leq 10^9 1≤ai≤109。
NOIP1998 提高组 第二题
1.题意解析
首先,考虑到这题需要拼接数字,直接想到用字符串存储数字。
那这道题就被简化成了如何排序字符串,使其组合出来的数最大。大部分同学(包括我)会写出这样的代码。
bool cmp(string a,string b)
{
if(a.size()==b.size())
return a>b;
return a.size()>b.size();
}
但只需要带入一组数据:
2
9 11
得到119
,而最优解是911
。
那该怎么办呢?难道要逐位比较字符串的数字大小吗?这样太麻烦了。我们可以这样写:
bool cmp(string x,string y)
{
return x+y>y+x;
}
这是什么意思呢?在字符串中,+
是拼接的意思。例如"abc"+"edf"="abcdef"
。这个语句的意思就是,x
后面拼接y
比y
后面拼接x
要大,那么按x y
的顺序排列,否则按y x
的顺序排列。
例如,对于123
和19
。调用cmp
函数,得到两个拼接后的字符串:12319
和19123
。通过比较得知,"12319"<"19123"
,经过排序后,得到"19123"
。
再根据数学归纳法,每一次这样的交换都是局部最优解,合起来自然就变成了全局最优解。
如果想看详细证明,可以点这。
2.AC代码
#include<bits/stdc++.h>
using namespace std;
bool cmp(string x,string y)//重点部分
{
return x+y>y+x;
}
int main()
{
int n;
string a[30];//定义字符串数组存储数字
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1,cmp);//排序
for(int i=1;i<=n;i++)
cout<<a[i];
return 0;
}
喜欢就订阅此专辑吧!
【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。
欢迎扫码关注蓝胖子编程教育