跳到主要内容
原文282 词数1 分钟

题解:P1012 [NOIP 1998 提高组] 拼数

概述

给定 n 个正整数,把它们首尾相接拼成一个数,求能组成的最大整数。关键在排序的比较准则:对两个数字串 x 和 y,若拼接 xy 大于拼接 yx 则 x 应排在前。可证该关系构成严格弱序,且交换任意相邻逆序对都会使结果严格增大,因此按此准则降序排列即为最优。时间复杂度为 O(n log n) 级别。

题意简述​

给定 nn 个正整数 aia_i,将它们首尾相接,求能组成的最大整数。

解题思路​

定义字符串集合 SS 上的二元关系 ≻\succ:

x≻y  ⟺  xy‾>yx‾x\succ y\iff\overline{xy}>\overline{yx}

其中 xy‾\overline{xy} 表示字符串 xx 和 yy 的拼接。

设 v(s)v(s) 为字符串 ss 对应的数值,l(s)l(s) 为 ss 的长度。构造映射 φ:S→R\varphi:S\to\mathbb{R}:

φ(s)=v(s)10l(s)−1\varphi(s)=\frac{v(s)}{10^{l(s)}-1} x≻y  ⟺  v(x)10l(y)+v(y)>v(y)10l(x)+v(x)  ⟺  v(x)(10l(y)−1)>v(y)(10l(x)−1)  ⟺  v(x)10l(x)−1>v(y)10l(y)−1  ⟺  φ(x)>φ(y)\begin{aligned} x\succ y & \iff v(x)10^{l(y)}+v(y)>v(y)10^{l(x)}+v(x) \\ & \iff v(x)\left(10^{l(y)}-1\right)>v(y)\left(10^{l(x)}-1\right) \\ & \iff\frac{v(x)}{10^{l(x)}-1}>\frac{v(y)}{10^{l(y)}-1} \\ & \iff\varphi(x)>\varphi(y) \end{aligned}

由实数域上 >> 的传递性和非对称性,可知 ≻\succ 在 SS 上满足 严格弱序。

假设最优排列 PP 存在相邻逆序 pi+1≻pip_{i+1}\succ p_i,交换两者得到 P′P'。

由于 pi+1pi‾>pipi+1‾\overline{p_{i+1}p_i}>\overline{p_ip_{i+1}},且交换不影响前后缀的数值贡献。故 P′P' 总数值严格增大,与 PP 为最优解矛盾。

因此,最优解为按 ≻\succ 降序的排列。

时间复杂度为 O(nlog⁡nlog⁡ai)O(n\log n\log a_i)。

参考代码​

267 Bcpp
#include <bits/stdc++.h>
using namespace std;

int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin>>n;
vector<string> a(n);
for(auto &s:a)cin>>s;
sort(a.begin(),a.end(),[](auto x,auto y){return x+y>y+x;});
for(auto s:a)cout<<s;
return 0;
}