1198. Substring
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
Dr lee cuts a string S into N pieces,s[1],…,s[N].
Now, Dr lee gives you these N sub-strings: s[1],…s[N]. There might be several possibilities that the string S could be. For example, if Dr. lee gives you three sub-strings {“a”,“ab”,”ac”}, the string S could be “aabac”,”aacab”,”abaac”,…
Your task is to output the lexicographically smallest S.
Input
The first line of the input is a positive integer T. T is the number of the test cases followed.
The first line of each test case is a positive integer N (1 <=N<= 8 ) which represents the number of sub-strings. After that, N lines followed. The i-th line is the i-th sub-string s[i]. Assume that the length of each sub-string is positive and less than 100.
Output
The output of each test is the lexicographically smallest S. No redundant spaces are needed.
Sample Input
13aabac
Sample Output
aabac
Problem Source
ZSUACM Team Member
个人总结:这题的主要理解障碍在s1+s2和s2+s1的比较上,为什么通过这样比较子串,最后得到的字符串就是字典排序最小的呢。大概可以这么来解释:
假设所有可能的字符串如下:
s1 s2 s3
s1 s3 s2
s2 s1 s3
s2 s3 s1
s3 s2 s1
s3 s1 s2
如果s3s2s1是字典排序最小的话,那么
s3s2s1 < s1s2s3 => 不作比较s3s2s1 < s1s3s2 => 不作比较
s3s2s1 < s2s1s3 => 不作比较
s3s2s1 < s2s3s1 => s3 + s2 < s2 + s3 (1)
s3s2s1 < s3s1s2 => s2 + s1 < s1 + s2 (2)
由(1)和(2)可以得出s3 + s1 < s1 +s3.
从上面我们可以知道,最小字典排序的字符串,它的任意子串组合还是保持一致的顺序,也就是s3s2s1的子串无论怎么组合,都必须保持321的前后顺序。
我们可以想像穷举了所有可能性,然后通过交换子串的位置,从s1s2s3调整倒s1s3s2,它的字典排序往前了,再调整倒s3s1s2,它的字典排序又往前了,最后调整倒s3s2s1,它满足所有子串都是组合都是最小的,那么就是我们所要得到的了。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int Compare(const string& str1, const string& str2);
int main() {
int T = 0;
cin >>T;
while (T--) {
int n;
cin >>n;
vector<string> str;
for (int i = 0; i < n; i ++) {
string substr;
cin >>substr;
int pos = 0;
if (str.empty()) {
str.push_back(substr);
} else {
bool flag = true;
for (pos = 0; pos < str.size(); pos ++) {
int result = Compare(substr, str.at(pos));
if (result == -1) {
flag = false;
str.insert(str.begin() + pos, substr);
break;
} else if (result == 0) {
flag = false;
break;
}
}
if (flag) {
str.push_back(substr);
}
}
}
for (size_t i = 0; i < str.size(); i ++)
cout <<str.at(i);
cout <<endl;
}
return 0;
}
int Compare(const string& str1, const string& str2) {
for (int i = 0; i < str1.size() && i < str2.size(); i ++) {
if (str1.at(i) < str2.at(i)) {
return -1;
} else if (str1.at(i) > str2.at(i)) {
return 1;
}
}
if (str1 + str2 < str2 + str1) {
return -1;
} else {
return 1;
}
}