#include <bits/stdc++.h>
using namespace std;
int n,tot;
int f[30],G[30][30],v[30],res[30],h[30];
//f记录入度,G记录前后,v记录是否入队,res中转,h记录对应顺序
string s[50010];
stack<int> r;
int main()
{
memset(f,0x3f,sizeof(f));
cin>>n;
for(int i=1;i<=n;i++) cin>>s[i];
for(int i=1;i<n;i++){
if(s[i]==s[i+1]) //完全相同,下一个
continue;
if(s[i+1].find(s[i])==0) //后一个包含前一个,没有比较的意义
continue;
if(s[i].find(s[i+1])==0){//前一个包含后一个,字典错误(与上一个相反)
puts("0");
return 0;
}
int x=0;
while(s[i][x]==s[i+1][x]) //寻找不同字母
x++;
int a=s[i][x]-'a'+1,b=s[i+1][x]-'a'+1;
if(G[b][a]){ //这里a在b前,而之前b在a前,前后矛盾,字典错误,结束
puts("0");
return 0;
}
G[a][b]=1;//存储
if(!v[a]) v[a]=1,f[a]=0;
if(!v[b]) v[b]=1,f[b]=1;
else f[b]++;//入度加一
}
memset(v,0,sizeof(v));
for(int i=1;i<30;i++)
if(!f[i])
r.push(i),v[i]=1;
while(r.size()) {//拓扑排序
int x=r.top(); r.pop();
res[++tot]=x;//记录当前
for(int i=1;i<30;i++) {
if(G[x][i]) f[i]--;//入度减一
if(!f[i]&&!v[i])
r.push(i),v[i]=1;
}
}
for(int i=1;i<=tot;i++)
h[res[i]]=i;
string que,ans; //que是被感染的字符串,ans是答案
cin>>que;
for(int i=0;i<que.length();i++) {
if(!h[que[i]-'a'+1]){//字典不完整,找不到对应字符
puts("0");
return 0;
}
ans+=(char)(h[que[i]-'a'+1]+'a'-1);//记录答案
}
cout<<ans<<endl;
return 0;
}
1396 病毒(virus)
最新推荐文章于 2025-01-28 20:04:50 发布