字典树,怎么是字典树呢,把所有的电话都存进去,电话的子串也存进去,每个节点标记上他是第几个数的,有个cnt计数。最后每个数输出最短的那个数。
代码不长很好理解。
#include <bits\stdc++.h>
using namespace std;
#define pb() push_back()
const int MAX=10;
typedef struct TrieNode //Trie结点声明
{
int cnt,now; //now 代表是第几个数字的节点,cnt代表是否是一次
struct TrieNode *next[MAX]; //儿子分支
}Trie;
void insert1(Trie *root,const char *s,int now1) //将单词s插入到字典树中
{
if(root==NULL||*s=='\0')
return;
int i;
Trie *p=root;
while(*s!='\0')
{
if(p->next[*s-'0']==NULL) //如果不存在,则建立结点
{
Trie *temp=(Trie *)malloc(sizeof(Trie));
for(i=0;i<MAX;i++)
{
temp->next[i]=NULL;
}
temp->now=now1;
temp->cnt=1;
p->next[*s-'0']=temp;
p=p->next[*s-'0'];
}
else
{
p=p->next[*s-'0'];
if(p->now!=now1)
p->now=now1,p->cnt++;
}
s++;
}
}
string s1[70003];
void sear(Trie *root,string s2)
{
if(root==NULL)return;
for(int i=0;i<MAX;i++)
{
if(root->next[i]!=NULL)
{
char c=(i+'0');
if(root->next[i]->cnt==1)
{
if(s1[root->next[i]->now].length()>s2.length()+1||s1[root->next[i]->now].length()==0)
{
s1[root->next[i]->now]=s2;
s1[root->next[i]->now]+=c;
}
}
sear(root->next[i],s2+c);
}
}
}
int main(){
//freopen("test.in","r",stdin);
ios::sync_with_stdio(false);
int n;
cin>>n;
char s[11];
Trie *root= (Trie *)malloc(sizeof(Trie));
for(int i=0;i<MAX;i++)
{
root->next[i]=NULL;
}
root->cnt=0;
root->now=-1;
for(int i=1;i<=n;i++)
{
cin>>s;
for(int j=0;j<9;j++)
{
insert1(root,s+j,i);
}
}
for(int i=1;i<=n;i++)s1[i]="";
sear(root,"");
for(int i=1;i<=n;i++)
cout<<s1[i]<<endl;
return 0;
}