Description
给出 n n n个字符串,要求用这 n n n个字符串构成一个新字符串,构造方式如下:初始为空串,之后依次放入字符串,对于当前要放入的字符串,去掉其最长的前缀使得该前缀是当前已经构造的字符串的子序列,之后把剩余部分接在所构造字符串后面,问最终字符串
Input
第一行一整数 T T T表示用例组数,每组用例首先输入一整数 n n n表示字符串数量,之后输出 n n n个字符串 s 1 , . . . , s n s_1,...,s_n s1,...,sn
( 1 ≤ T ≤ 3 , 1 ≤ n ≤ 1 0 6 , 1 ≤ ∣ s i ∣ , ∑ ∣ s i ∣ ≤ 1 0 6 ) (1\le T\le 3,1\le n\le 10^6,1\le |s_i|,\sum |s_i|\le 10^6) (1≤T≤3,1≤n≤106,1≤∣si∣,∑∣si∣≤106)
Output
输出最终字符串
Sample Input
2
2
lubenwei
niubi
3
aa
ab
abb
Sample Output
lubenweiubi
aabb
Solution
维护每个字母在新字符串中出现的位置,对于要插入的字符串,从前到后考虑二分找到最靠前位置的字符即可
Code
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
#define maxn 1000005
int T,n;
char s[maxn],c[maxn];
vector<int>v[27];
vector<int>::iterator it;
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
int m=0;
for(int i=0;i<26;i++)v[i].clear();
while(n--)
{
scanf("%s",c);
int len=strlen(c);
int p=0;
for(int i=0;i<len;i++)
{
int t=c[i]-'a';
it=lower_bound(v[t].begin(),v[t].end(),p);
if(it==v[t].end())
{
while(i<len)
{
s[m]=c[i];
v[c[i]-'a'].push_back(m);
m++;
i++;
}
break;
}
p=(*it)+1;
}
}
s[m]='\0';
printf("%s\n",s);
}
return 0;
}