1198. Substring题解

题目:

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;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值