​https://qduoj.com/problem/65​

提前把所有字符串按字典序排序 然后插入字符串时比较一下 维护以当前节点结尾字符串的所有后缀中的最短的那个字符串

#include <bits/stdc++.h>
using namespace std;
#define N 0x3f3f3f3f

struct node1
{
char ch[30];
};

struct node2
{
node2 *next[26];
int len;
int id;
};

node1 ary[20010];
node2 *root;
int n,q;

bool cmp(node1 n1,node1 n2)
{
return strcmp(n1.ch,n2.ch)<0;
}

void getnode(node2 *& ptr)
{
int i;
ptr=new node2;
for(i=0;i<26;i++) ptr->next[i]=NULL;
ptr->len=N,ptr->id=-1;
}

void destruct(node2 *ptr)
{
int i;
for(i=0;i<26;i++)
{
if(ptr->next[i]!=NULL) destruct(ptr->next[i]);
}
delete ptr;
}

void update(node2 *ptr,char *ch,int id,int cur,int len)
{
if(ptr->next[ch[cur]-'a']==NULL) getnode(ptr->next[ch[cur]-'a']);
if(ptr->next[ch[cur]-'a']->len>len) ptr->next[ch[cur]-'a']->len=len,ptr->next[ch[cur]-'a']->id=id;
if(cur==len-1) return;
update(ptr->next[ch[cur]-'a'],ch,id,cur+1,len);
}

int query(node2 *ptr,char *ch,int cur,int len)
{
if(ptr->next[ch[cur]-'a']==NULL) return -1;
if(cur==len-1) return ptr->next[ch[cur]-'a']->id;
return query(ptr->next[ch[cur]-'a'],ch,cur+1,len);
}

int main()
{
int t,cas,i,res;
char ch[30];
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%s",ary[i].ch);
}
sort(ary+1,ary+n+1,cmp);
getnode(root);
for(i=1;i<=n;i++)
{
update(root,ary[i].ch,i,0,strlen(ary[i].ch));
}
printf("Case %d:\n",cas);
scanf("%d",&q);
while(q--)
{
scanf("%s",ch);
res=query(root,ch,0,strlen(ch));
if(res==-1) printf("-1\n");
else printf("%s\n",ary[res].ch);
}
destruct(root);
}
return 0;
}