【题解】【排序】—— [NOIP1998 提高组] 拼数

[NOIP1998 提高组] 拼数

题目描述

设有 n n n 个正整数 a 1 … a n a_1 \dots a_n a1an,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。

输入格式

第一行有一个整数,表示数字个数 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 1n20 1 ≤ a i ≤ 1 0 9 1 \leq a_i \leq 10^9 1ai109

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后面拼接yy后面拼接x要大,那么按x y的顺序排列,否则按y x的顺序排列。

    例如,对于12319。调用cmp函数,得到两个拼接后的字符串:1231919123。通过比较得知,"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;
}

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子教编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值