Sicily 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

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


s3s2s1 < s2s3s1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值