【2025牛客五一集训派对day4 C】题解

比赛链接

题目链接

题目大意

给定 N N N 个字符串,问怎么拼接使得组成的整数最小。

Solution

结论:将数组 s s s 按照 s i + s j < s j + s i s_i + s_j < s_j + s_i si+sj<sj+si 排序输出是最优的。

        • 是字符串拼接,例如 1 + 2 = 12 1 + 2 = 12 1+2=12;
  • < < < 是按照字典序来的,例如 10 < 2 10 < 2 10<2, 23 < 232 23 < 232 23<232。

正解是 O ( N ) O(N) O(N) 的 Trie + z \text{Trie + z} Trie + z 函数,但是不太会,所以下面只讲这样排序可行的证明。

考虑偏序关系 A ≺ B A \prec B A≺B 表示 A B < B A AB < BA AB<BA,其中 A B = A + B , B A = B + A AB = A + B, \ BA = B + A AB=A+B, BA=B+A。

首先考虑三个等长字符串 A , B , C A, B, C A,B,C,若 A ≺ B A \prec B A≺B 且 B ≺ C B \prec C B≺C,显然有 A ≺ C A \prec C A≺C。

  • 设 L = ∣ A ∣ = ∣ B ∣ = ∣ C ∣ L = |A| = |B| = |C| L=∣A∣=∣B∣=∣C∣, A ≺ B A \prec B A≺B 表示 A B < B A AB < BA AB<BA,那么一定可以找到最小的 i ∈ 1 , L i \in 1, L i∈1,L 使得 A i < B i A_i < B_i Ai<Bi,否则 A = B A = B A=B,就有 A B = B A AB = BA AB=BA,矛盾;
  • 同理可以找到最小的 j ∈ 1 , L j \in 1, L j∈1,L 使得 B j < C j B_j < C_j Bj<Cj;
  • 若 i = j i = j i=j,则 A i < B i = B j < C j A_i < B_i = B_j < C_j Ai<Bi=Bj<Cj;
  • 若 i < j i < j i<j,则 A i < B i = C i A_i < B_i = C_i Ai<Bi=Ci;
  • 若 i > j i > j i>j,则 A j = B j < C j A_j = B_j < C_j Aj=Bj<Cj。
  • 所以 A < C A < C A<C。
  • 而 ∣ A ∣ = ∣ C ∣ |A| = |C| ∣A∣=∣C∣,拼起来也不改变前 L L L 个字符,所以 A C < C A AC < CA AC<CA,即 A ≺ C A \prec C A≺C。

设 A n = A A ⋯ A ⏟ 共 n 个 A A^n = \underbrace{AA \cdots A}_{共 n 个 A} An=共n个A AA⋯A,下证:对任意字符串 A , B A, B A,B, A ≺ B A \prec B A≺B 等价于 A n ≺ B A^n \prec B An≺B。

首先证明 A ≺ B ⇒ A n ≺ B A \prec B \Rightarrow A^n \prec B A≺B⇒An≺B。考虑数学归纳法。

由 A ≺ B A \prec B A≺B 有 A B < B A AB < BA AB<BA,在前面同时加上 A A A,得到 A A B < A B A AAB < ABA AAB<ABA,在后面同时加上 A A A,得到 A B A < B A A ABA < BAA ABA<BAA,这就得到了 A A B < B A A AAB < BAA AAB<BAA,也就有 A 2 B < B A 2 A^2B < BA^2 A2B<BA2,即 A 2 ≺ B A^2 \prec B A2≺B。

设 A n − 1 ≺ B A^{n - 1} \prec B An−1≺B,那么有 A n − 1 B < B A n − 1 A^{n - 1}B < BA^{n - 1} An−1B<BAn−1,在前面同时加上 A A A,得到 A n B < A B A n − 1 A^nB < ABA^{n - 1} AnB<ABAn−1,在 A B < B A AB < BA AB<BA 后面同时加上 A n − 1 A^{n - 1} An−1,得到 A B A n − 1 < B A n ABA^{n - 1} < BA^n ABAn−1<BAn,于是有 A n B < B A n A^nB < BA^n AnB<BAn,则 A n ≺ B A^n \prec B An≺B。

而 A ≺ B n A \prec B^n A≺Bn 同理可证(就是把同时加 A A A 改成同时加 B B B)。

接着证明 A n ≺ B ⇒ A ≺ B A^n \prec B \Rightarrow A \prec B An≺B⇒A≺B。考虑反证法。

若 A ⊀ B A \nprec B A⊀B,那么一定有 A B = B A AB = BA AB=BA 或 B ≺ A B \prec A B≺A。

  • 若 A B = B A AB = BA AB=BA,则 A n B = A n − 1 A B = A n − 1 B A = ⋯ = B A n A^nB = A^{n - 1}AB = A^{n - 1}BA = \cdots = BA^n AnB=An−1AB=An−1BA=⋯=BAn,与 A n ≺ B A^n \prec B An≺B 矛盾;
  • 若 B ≺ A B \prec A B≺A,则 B ≺ A n B \prec A^n B≺An(这是上一段证明推导出的结论),与 A n ≺ B A^n \prec B An≺B 矛盾。

因此 A ≺ B ⟺ A n ≺ B ⟺ A ≺ B n A \prec B \Longleftrightarrow A^n \prec B \Longleftrightarrow A \prec B^n A≺B⟺An≺B⟺A≺Bn,再进一步就是

A ≺ B ⟺ A n ≺ B m . A \prec B \Longleftrightarrow A^n \prec B^m. A≺B⟺An≺Bm.

其中 n , m n, m n,m 是任意正整数。

这样,对于三个长度不同的字符串 A , B , C A, B, C A,B,C,我们可以找到它们的最小公倍数 L = lcm ( ∣ A ∣ , ∣ B ∣ , ∣ C ∣ ) L = \text{lcm}(|A|, |B|, |C|) L=lcm(∣A∣,∣B∣,∣C∣),然后拼接成长度均为 L L L 的字符串进行比较,即若

A ≺ B ≺ C , A \prec B \prec C, A≺B≺C,

则

A L ∣ A ∣ ≺ B L ∣ B ∣ ≺ C L ∣ C ∣ , A^{\frac{L}{|A|}} \prec B^{\frac{L}{|B|}} \prec C^{\frac{L}{|C|}}, A∣A∣L≺B∣B∣L≺C∣C∣L,

而长度相同的传递性显然,所以有

A L ∣ A ∣ ≺ C L ∣ C ∣ , A^{\frac{L}{|A|}} \prec C^{\frac{L}{|C|}}, A∣A∣L≺C∣C∣L,

再由 A ≺ B ⟺ A n ≺ B m A \prec B \Longleftrightarrow A^n \prec B^m A≺B⟺An≺Bm,得到

A ≺ C . A \prec C. A≺C.

这样对于任意字符串传递性都保证了。

C++ Code

cpp 复制代码
#include <bits/stdc++.h>

template<class T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
    for (auto &x: v) {
        is >> x;
    }
    return is;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int N;
    std::cin >> N;

    std::vector<std::string> S(N);
    std::cin >> S;

    std::ranges::sort(S, [&](const auto &a, const auto &b) {
        return a + b < b + a;
    });

    for (const auto &s: S) {
        std::cout << s;
    }
    
    return 0;
}
相关推荐
D e re k ZH30 分钟前
C++ 并发、未定义行为与工程化难点(No 3)
数据结构·c++·算法·面试
释厄6231 小时前
同性线套娃律——圆面积必然=1+2+...+n 的求和·圆心不与 π 相关
java·人工智能·算法·1024程序员节
暴力求解2 小时前
C++ ---继承(二)
开发语言·c++·算法
码林拾遗WJ2 小时前
告警分级的自动化实测:模型判断 vs 人工拍板
人工智能·算法·自动化
Tisfy2 小时前
LeetCode 0453.最小操作次数使数组元素相等:两次遍历(反向思维)
算法·leetcode·题解·遍历·反向思维
君万2 小时前
【LeetCode每日一题】回溯:46. 全排列 78. 子集 39. 组合总和
算法·leetcode·go
Keep_Trying_Go3 小时前
Consistent-Point半监督人群计数算法详解
人工智能·深度学习·算法·计算机视觉·人群计数
在所不辞兄3 小时前
【零基础学智能仿真-69】综合项目——材料参数驱动的仿真研究
人工智能·深度学习·神经网络·算法·机器学习·1024程序员节
凉茶钱4 小时前
红黑树:用“颜色”换“平衡”,set 与 map 的底层发动机
开发语言·c++·红黑树
怕浪猫5 小时前
Super-agent 在各大模型厂商的应用情况
算法·面试·github