题目链接
题意:按时间顺序输入一串人名,输出的名字前缀不能与在他之前输入的名字前缀相同,如果名字与在他之前输入的完全相同,则输出全名和目前为止名字出现的次数。
思路:将每个人的名字构成一个字典树,将名字插入字典树时将p->num == 1之前的所有字符存入一个数组中(包括p->num==1),这个字符数组就是就是当前这个名字的前缀且与之前输入的名字的前缀不同。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#define ll long long
#define lowbit(x) ((~x+1)&x)
using namespace std;
const int N = 1e5+5;
int t,n;
char str[N][15];
char ans[N][15];
int num[N];
struct trie {
trie * next[27];
int num;
trie() {
for(int i=0; i<26; i++) next[i] = NULL;
num=0;
}
}root;
map<string,int>mp;
void insert(char str[],int num) {
trie *p = &root;
char temp[15]={'\0'};
int flag=1,cnt=0;
for(int i=0; str[i]; i++) {
if(p->next[str[i]-'a']==NULL)
p->next[str[i]-'a'] = new trie;
p=p->next[str[i]-'a'];
p->num++;
if(flag) {
temp[cnt++] = str[i];
if(p->num==1) flag=0;
}
}
strcpy(ans[num],temp);
}
int main() {
mp.clear();
cin>>n;
for(int i=1; i<=n; i++) {
cin>>str[i];
mp[str[i]]++;
insert(str[i],i);
if(mp[str[i]]>1) {
strcpy(ans[i],str[i]);
num[i] = mp[str[i]];
}
}
for(int i=1; i<=n; i++) {
if(num[i]) cout<<str[i]<<' '<<num[i]<<endl;
else cout<<ans[i]<<endl;
}
return 0;
}