拼数

拼数 洛谷

题目描述

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


输入格式

第一行有一个整数,表示数字个数 \(n\)

第二行有 \(n\) 个整数,表示给出的 \(n\) 个整数 \(a_i\)


输出格式

一个正整数,表示最大的整数


样例输入

3
13 312 343

样例输出

34331213

提示

对于全部的测试点,保证 \(1 \leq n \leq 20\)\(1 \leq a_i \leq 10^9\)


先来一点符号规定

  • \(\overline{AB}\) 表示将 \(A\)\(B\) 连接在一起所产生的字符串,如:\(A=123,B=456\)\(\overline{AB}=123456\)
  • \(A->B\) 表示 \(\overline{AB}>\overline{BA}\) ,也就是说 \(A\) 接在 \(B\) 前面比 \(B\) 接在 \(A\) 前面更优
  • \(\left\vert A \right\vert\),表示 \(A\) 的长度

这是一个贪心,先看代码,我再来解释

\(Code:\)

#include<bits/stdc++.h>
using namespace std;
int n;
const int N=25;
string a[N];

bool cmp(string x,string y){
	return x+y>y+x;
}
int main()
{
	scanf("%d",&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;
}

这份代码说当每一个 \(a_i\)\(a_{i+1}\) 满足 \(a_i->a_{i+1}\) 那么将数组输出出来便是答案

证明一下(证明为个人理解,可能并不严谨)


不难看出,当数组满足 \(a_1->a_2->a_3->...->a_n\) 时,此时依次输出便是答案

而我们知道,刚刚的那个排序保证了 \(a_1->a_2,a_2->a_3,a_3->a_4,...,a_n-1->a_n\)

现在需要证明的便成为了证明当 \(a_1->a_2\)\(a_2->a_3\) 那么 \(a_1->a_3\) (也就是证明传递性)

非常简单的证明,首先我们将 \(a_1,a_2,a_3\) 重新设为 \(A,B,C\)

那么便可以通过 \(A->B\) 推出以下东西

\[A->B\\ \overline{AB}>\overline{BA}\\ A\times 10^{\left\vert B \right\vert}+B>B\times 10^{\left\vert A \right\vert}+A\\ A\times (10^{\left\vert B \right\vert}-1)>B\times (10^{\left\vert A \right\vert}-1)\\ \frac{A}{10^{\left\vert A \right\vert}-1}>\frac{B}{10^{\left\vert B \right\vert}-1} \]

所以通过 \(B->C\) 也有 \(\frac{B}{10^{\left\vert B \right\vert}-1}>\frac{C}{10^{\left\vert C \right\vert}-1}\)

那么合并一下,便有 \(\frac{A}{10^{\left\vert A \right\vert}-1}>\frac{C}{10^{\left\vert C \right\vert}-1}\),轻松得到 \(A->C\)

得证

posted @ 2023-05-03 10:44  HEIMOFA  阅读(42)  评论(0)    收藏  举报