题目
设有n个正整数,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。
输入输出格式
输入格式
第一行有一个整数,表示数字个数n。
第二行有n个整数,表示给出的n个整数。
输出格式
一个正整数,表示最大的整数
输入输出样例
输入样例
3
13 312 343
输出样例
34331213
代码
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
string s;
}a[25];
int n;
bool cmp(node x,node y){
if(x.s+y.s>y.s+x.s){
return 1;
}
return 0;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].s;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
cout<<a[i].s;
}
return 0;
}
解析
我们先定义几个符号,(a,b是数字字符串)表示a+b也就是把a和b连起来写
abc(a,b,c都是数字符串)(当然再多几个字符串也没关系,跟上面一个意思)
a⩾b 表示正常的a大于等于b
a>=b a,b是数字字符串 表示a+b⩾b+a 注意区分这两个大于等于!
a*n a是数字字符串,n是正整数,表示把a连续写n遍形成的很长的字符串
下面开始证明。
从代码中可以看出,我们把a数组按这个 >= 符号降序排好序,再直接输出就是正确的答案了。容易发现,对于任意一种排列方式,只要相邻的两个数不满足前面的>=后面的,那么这种排列肯定不是最优的。也就是说,对于最优排列,肯定有第一个串>=第二个串,第二个串>=第三个串,第三个串>=第四个串 ... 依此类推。
经过这一些简单的推理,证明的思路实际上很清晰了:只需要再证明传递性(由a>=b且b>=c 能否推出a>=c)。这是最后的一步,也是关键的一步。
先证明一个性质: 如果a>=b,那么a*n>= b。 (思路:递推/数学归纳法)
由a>=b即ab⩾ba,可知aab⩾aba并且aba⩾baa,从而aab⩾baa也就是a*2>=b
由a*2>=b即aab⩾baa 又由ab⩾ba,可知aaab⩾abaa并且abaa⩾baaa
从而aaab⩾baaa,也就是 a*3>=b,依此类推,便能证得a*n>=b
类似地,由a>=b,也可以得到a>=b*n。 相反,如果a*n>=b或者a>=b*n,也能得到 a>=b。
有了这个结论,我们只要a,b,c各乘上一个合适的整数,不难证明传递性了。