【洛谷 P1012】[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

样例输入 #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 ≤ 1 0 9 1 \leq a_i \leq 10^9 1≤ai≤109。


思路

比较函数 cmp 用于确保拼接后的数值最大。

当用下面这个函数直接比较 x 和 y 的字典序时,虽然能通过大部分样例,但是仍有少量测试点 WA。

cpp 复制代码
bool cmp(string x, string y)
{
    return x > y;
}

为什么会这样呢?

举个例子:当有 32、321 这两个数字。

  1. 如果用 x > y 比较,即先比较再拼接,则 321 > 32,拼接后为 32132,但是显然 32132 < 32321,所以这样比较不对。

  2. 如果用 x + y > y + x 比较,即先拼接再比较,则 32321 > 32132,正确。

所以,对于两个字符串 x 和 y,如果 x+y 的字典序大于 y+x 的字典序,则认为 x 大于 y。得到比较函数 cmp 如下。

cpp 复制代码
bool cmp(string x, string y)
{
    return x + y > y + x;
}

AC代码

cpp 复制代码
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
#define AUTHOR "HEX9CF"
using namespace std;

const int N = 107;

int n;
string s[N];

bool cmp(string x, string y)
{
    return x + y > y + x;
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> s[i];
    }
    sort(s + 1, s + n + 1, cmp);
    for (int i = 1; i <= n; i++)
    {
        cout << s[i];
    }
    cout << endl;
    return 0;
}
相关推荐
贝壳69023 分钟前
一个2026年2月才上传的库,凭什么敢碰2009年就有人写烂的题目
算法
贝壳6901 小时前
同一道三亿位选型题,三个AI给了我三个答案,我把它们拉进同一台机器复跑
算法
青少儿编程课堂3 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会图形化考级:校园大富翁经营闯关解析
c++·python·算法·bfs·信息学竞赛
在所不辞兄4 小时前
为什么在新能源汽车电驱与热管理开发中,AI驱动的数字孪生和数据驱动仿真正在部分替代对物理台架与实车标定的依赖?
人工智能·深度学习·神经网络·算法·机器学习
I_belong_to_jesus14 小时前
C++关于分支预测的优化1
开发语言·c++·算法
Code_Solitude21 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司21 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP1 天前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀1 天前
背包DP(01背包+完全背包)
c++·算法