You're given a list of n strings a1, a2, ..., an. You'd like to concatenate them together in some order such that the resulting string would be lexicographically smallest.
Given the list of strings, output the lexicographically smallest concatenation.
The first line contains integer n — the number of strings (1 ≤ n ≤ 5·104).
Each of the next n lines contains one string ai (1 ≤ |ai| ≤ 50) consisting of only lowercase English letters. The sum of string lengths will not exceed 5·104.
Print the only string a — the lexicographically smallest string concatenation.
4 abba abacaba bcd er
abacabaabbabcder
5 x xx xxa xxaa xxaaa
xxaaaxxaaxxaxxx
3 c cb cba
cbacbc
题意,输入n个字符串,把它们连接起来使得字典序最小。
官方的方法是:
The problem was suggested by Lewin Gan lewin. The proof of the transitivity also belongs to him.
Let's sort all the strings by comparator a + b < b + a and concatenate them. Let's prove that it's the optimal answer. Let that operator be transitive (so if ). Consider an optimal answer with two strings in reverse order by that operator. Because of the transitivity of operator we can assume that pair of strings are neighbouring. But then we can swap them and get the better answer.
Let's prove the transitivity of operator. Consider the strings as the 26-base numbers. Then the relation a + b < b + a equivalent to . The last is simply the relation between real numbers. So we proved the transitivity of the relation a + b < b + a.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <queue>
typedef long long ll;
typedef long double ld;
using namespace std;
string s[60000];
bool cmp(const string& a, const string& b) {
return (a + b) < (b + a);
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i)
cin >> s[i];
sort(s, s + n, cmp);
for (int i = 0; i < n; ++i)
cout << s[i];
cout << "\n";
return 0;
}