原题链接:病毒(virus)
解题思路:单词依字典序排列, 因此可以判断单词中字符是否存在拓扑序, 如果存在, 则遍历病毒字符串中的字符, 如果每一个字符都存在映射的索引, 则依照索引0 为‘a’ 依次输出, 否则输出0;
注意事项:在比较字典单词的字符时, 注意判断是否越界; 进行拓扑排序时,判断是否具有拓扑序
参考代码:
#include<iostream> #include<stack> #include<cstring> using namespace std; const int N = 1e5 + 10; stack<int> stk; int g[30][30]; int ind[30],v[30],map[30]; //ind[] 入度, v[]是否应该入栈,map[]字符映射 string s[N],ans,str,res;// s[] 输入的感染字典, str 输入的感染字符串,res感染字符拓扑排序 //构建图 void build_graph(int n){ for(int i = 1; i <= n; i ++){ int j = 0; while(s[i][j] == s[i+1][j] && j < s[i].size() && j < s[i + 1].size()){ j ++; } if(j == s[i].size() || j == s[i+1].size()) continue; g[s[i][j] - 'a'][s[i + 1][ j] - 'a' ] = 1; ind[s[i + 1][j] - 'a'] += 1; v[s[i][j] - 'a'] = 1; v[s[i + 1][j] - 'a'] = 1; } return; } int main() { int n; cin >> n; for(int i = 1; i <= n; i ++){ cin >> s[i]; } //构建图 build_graph(n); cin >> str; //拓扑排序 for(int i = 0; i <30; i ++){ if(!ind[i] && v[i] == 1){ stk.push(i); v[i] = 0; } } while(!stk.empty()){ int c = stk.top(); stk.pop(); res += char(c + 'a'); for(int i = 0; i < 30; i ++){ if(g[c][i]) ind[i] --; if(ind[i] == 0 && v[i]) { stk.push(i); v[i] = 0; } } } //如果res为空, 则不存在拓扑排序, 输出结果0 if(res.empty()){ cout << 0; return 0; } memset(map, -1, sizeof(map)); //建立感染字符与索引的映射 for(int i = 0; i < res.size(); i ++){ map[res[i]] = i; } for(int i = 0; i < str.size(); i ++){ if(map[str[i]]== -1){ cout << 0; return 0; } //从a开始按照索引位置拼接字符串 ans += char(map[str[i]] + 'a'); } cout << ans <<endl; return 0; }
0.0分
2 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复