最近情报人员得到了一些经过加密的文章,每个单词都很长。破译人员想到先把单词简化一下,方法是把每个单词尽量取短些的前缀,但所取的前缀不能是其他单词的前缀。
这个任务现在就交给你来完成。
解释:“字符串s1是s2的前缀”是说把字符串s2的后面去掉某些,只保留与s1的长度时,s2就与s1完全相同。如:“abc”是“abcde”和“abc”的前缀,但不是“ababc”的前缀。
第一行一个整数N,表示单词个数。 下面有N行,每行一个单词。
共N行,每行一个单词,是对应上面的N个单词化简后的单词。
3 abc efg ijh
a e I
数据范围 单词数N,1≤N≤50;每个单词的长度不超过50;并且单词都有小写字母构成。 保证所给单词没有一个单词是另一个单词的前缀。
#include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<string> #include<cstdio> using namespace std; int n; string s[55]; int num=0; struct pointt { int tr[26],cd; pointt() {cd=0;} }a[2505]; void ins(string s) { int len=s.size(),p=0; for(int i=0;i<len;i++) { int ch=int(s[i]-'a'); if(a[p].tr[ch]==0) a[p].tr[ch]=++num; p=a[p].tr[ch]; a[p].cd++; } } void matchh(string s) { int len=s.size(),p=0; for(int i=0;i<len;i++) { int ch=int(s[i]-'a'); printf("%c",s[i]); p=a[p].tr[ch]; if(a[p].cd==1) { cout<<endl; break; } } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>s[i]; ins(s[i]); } for(int i=1;i<=n;i++) matchh(s[i]); return 0; }
