测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A28836. 病毒(virus)

填空题 困难

题目描述

病毒(virus)

题目描述

有一天,小y突然发现自己的计算机感染了一种病毒!还好,小y发现这种病毒很弱,只是会把文档中的所有字母替换成其它字母,但并不改变顺序,也不会增加和删除字母。

现在怎么恢复原来的文档呢!小y很聪明,他在其他没有感染病毒的机器上,生成了一个由若干单词构成的字典,字典中的单词是按照字母顺序排列的,他把这个文件拷贝到自己的机器里,故意让它感染上病毒,他想利用这个字典文件原来的有序性,找到病毒替换字母的规律,再用来恢复其它文档。

现在你的任务是:告诉你被病毒感染了的字典,要你恢复一个字母串。

输入

第一行为整数K(≤50000),表示字典中的单词个数。

以下K行,是被病毒感染了的字典,每行一个单词。

最后一行是需要你恢复的一串字母。

所有字母均为小写。

输出

输出仅一行,为恢复后的一串字母。当然也有可能出现字典不完整、甚至字典是错的情况,这时请输出一个0。

输入样例

6
cebdbac
cac
ecd
dca
aba
bac
cedab

输出样例

abcde

参考答案

#include<bits/stdc++.h> using namespace std; #define N 30 int edge[N][N], deg[N]; set<int> st;//保存被感染后的所有字符 map<char, char> mp;//mp[i]:感染后的字符i原来是什么字符 bool topoSort()//如果返回值为false,则该有向图没有拓扑排序或没有唯一拓扑排序 { int ct = 0; char alph = 'a'; queue<int> que; for(int v : st) if(deg[v] == 0) { que.push(v); ct++; } if(ct > 1)//入度为0的应该只有1个 return false; while(!que.empty()) { int u = que.front(); que.pop(); mp[u+'a'] = alph++;//拓扑排序序列对应a,b,c... ct = 0; for(int v : st) if(edge[u][v] && --deg[v] == 0) { que.push(v); ct++; } if(ct > 1)//删掉u后,入度为0的应该只有1个 return false; } return mp.size() == st.size();//st中每个字符都有对应的字符,图中才没有环,是完成了拓扑排序 } int main() { string s, ls, t;//ls:上一个字符串 int k; cin >> k; for(int j = 1; j <= k; ++j) { cin >> s; for(char c : s)//把所有感染后的字符串中的字符加入st st.insert(c-'a'); if(j == 1)//第一次循环只记录ls { ls = s; continue; } for(int i = 0; i < s.length(); ++i) { if(s[i] != ls[i]) { if(ls[i] != '\0') { edge[ls[i]-'a'][s[i]-'a'] = 1;//ls[i]到s[i]有一条边 deg[s[i]-'a']++; } break; } } ls = s; } cin >> t;//待转换字符串 bool hasAns = topoSort(); for(char c : t) if(st.count(c-'a') == 0)//如果出现不存在的字符 hasAns = false; if(hasAns) for(char c : t) cout << mp[c]; else cout << 0; return 0; }
上一题 下一题