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
1
3
a
ab
ac
Sample Output
aabac
Problem Source
ZSUACM Team Member
题意:第一行为测试用例个数,每个用例第一行为子串个数,接下来为N个子串。找出包含所有子串(每个子串仅出现一次)且字典序最小的长串并打印。
题解:由于题目限制子串个数为8以内,所以用枚举的方法是可以解的,只需存储所有结果并排序即可。但是如果是8以外呢?当N较大时,枚举肯定是不行的,时间和空间都会不够,直接将子串排序再输出是一个比较好的方法,如:a,e,b,排序后是a,b,e,输出就是正确的结果,但是直接对子串进行一半的排序也会出现问题,比如子串集为“a,b,ba”时,进行排序将会得到“a,b,ba”,而“a,ba,b”才是正确的结果。一种比较简洁的方法是重新定义对子串排序的规则,比如子串“b,ba”,要对其进行排序,先令x = b + ba = "bba", y = ba + b = "bab",再根据组合后的x,y来判断字典序大小,此时可以看到x > y,即排序后为ba,b,这就是我们需要的结果,我利用快排来对本题进行排序,代码如下:
#include <iostream>
#include <string>
using namespace std;
void quicksort(string* A, int start, int end);
int partition(string* A, int start, int end);
int main(){
int test_case;
cin>>test_case;
while(test_case--){
int n;
cin>>n;
string* substring_set = new string[n];
for(int i = 0; i < n; i++){
cin>>substring_set[i];
}
quicksort(substring_set, 0, n-1);
for(int i = 0; i < n; i++){
cout<<substring_set[i];
}
cout<<endl;
}
return 0;
}
void quicksort(string* A, int start, int end){
if(start < end){
int q = partition(A, start, end);
quicksort(A, start, q-1);
quicksort(A, q+1, end);
}
}
int partition(string* A, int start, int end){
string x = A[end];
int i = start - 1;
for(int j = start; j < end; j++){
string a,b;
a = A[j] + x;
b = x + A[j];
if(a <= b){
i += 1;
string temp = A[i];
A[i] = A[j];
A[j] = temp;
}
}
string temp = A[i+1];
A[i+1] = A[end];
A[end] = temp;
return i+1;
}