//字符串的前缀处理问题:Trie树的运用
//同时前缀标出让其没有歧义:思路就是从子串中在Trie树中找到能够唯一标示的第一个字符为止
//Accepted 276K 16MS
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
typedef struct node{
int L;//以当前开头的词的数目
char value;
node*child;
node* next;
}*Node;
Node GTireTree;//地图存储
static int n;
static char str[1002][22];
static void initTree()
{
GTireTree = (Node)malloc(sizeof(node));
GTireTree->child = NULL;
GTireTree->next = NULL;
GTireTree->value = '0';
GTireTree->L = 0;
}
static void addWord(char*str)
{
int len = strlen(str);
Node p = GTireTree;
p->L++;
for (int i=0;i<len;++i)
{
char ch = str[i];
Node d = p->child;
if (d==NULL)
{
Node tnode = (Node)malloc(sizeof(node));
tnode->child = NULL;
tnode->next = NULL;
tnode->value = ch;
p->child = tnode;
tnode->L = 1;
d = tnode;
//printf("生成结点%c ",ch);
}
else{
Node last;
while(d!=NULL&&d->value!=ch)
{
last = d;
d = d->next;
}
if (d==NULL)
{
d = (Node)malloc(sizeof(node));
d->child = NULL;
d->next = NULL;
d->value = ch;
d->L = 1;
last->next = d;
//printf("生成结点%c ",ch);
}
else
{
d->L++;
//printf("已经存在结点%c ",ch);
}
}
p = d;
}
//printf("\n");
}
static int search(char*str)
{
int len = strlen(str);
Node p = GTireTree;
int time = 0;
for (int i=0;i<len;++i)
{
char ch = str[i];
Node d = p->child;
while(d!=NULL&&d->value!=ch)
d = d->next;
if (d==NULL)
break;
if (i==len-1)
time = d->L;
p = d;
}
return time;
}
static void solve()
{
int i,j;
for (i=0;i<n;++i)
{
int len = strlen(str[i]);
char strdest[22];
int times = 0;
for (j=1;j<=len;++j)
{
strncpy(strdest,str[i],j);
strdest[j] = '\0';
times = search(strdest);
if (times==1)
break;
}
printf("%s",str[i]);
if (j>=len)
{
printf(" %s\n",str[i]);
}
else if (times==1)
{
printf(" %s\n",strdest);
}
}
}
int main()
{
initTree();
n = 0;
while(scanf("%s",str[n])!=EOF)
{
addWord(str[n]);
n++;
}
solve();
return 0;
}