算法问题实战策略 DICTIONARY

地址 https://algospot.com/judge/problem/read/DICTIONARY

解法 构造一个26字母的有向图 判断无回路后 就可以输出判断出来的字符序了

比较各个字母的先后次序不必用一个单词分别同其他单词比较 只需要将临近的两个单词一一比较即可

证明如下

算法1 中判断有无回路 采取的是DFS方法 

代码

复制代码
  1 #include <iostream>
  2 #include <string>
  3 #include <vector>
  4 #include <algorithm>
  5 #include <memory.h>
  6 
  7 using namespace std;
  8 
  9 /*
 10 3
 11 3
 12 ba
 13 aa
 14 ab
 15 5
 16 gg
 17 kia
 18 lotte
 19 lg
 20 hanhwa
 21 6
 22 dictionary
 23 english
 24 is
 25 ordered
 26 ordinary
 27 this
 28 ======================================================
 29 INVALID HYPOTHESIS
 30 ogklhabcdefijmnpqrstuvwxyz
 31 abcdefghijklmnopqrstuvwxyz
 32 */
 33 
 34 int n;
 35 
 36 vector<pair<int, int>> vvmap;
 37 
 38 void Compare(string s1, string s2)
 39 {
 40     int len = min(s1.size(),s2.size());
 41 
 42     for (int i = 0; i < len; i++) {
 43         if (s1[i] == s2[i]) continue;
 44         int a = s1[i] - 'a';
 45         int b = s2[i] - 'a';
 46         vvmap.push_back({a,b});
 47         break;
 48     }
 49 }
 50 
 51 
 52 vector<int>  seen, order;
 53 
 54 void dfs(int here) {
 55     seen[here] = 2;
 56     for (int there = 0; there < 26; ++there) {
 57         if ( find(vvmap.begin(),vvmap.end(),pair<int,int>(here,there)) != vvmap.end()
 58                     && seen[there] == 1 )
 59             dfs(there);
 60     }
 61     order.push_back(here);
 62 }
 63 
 64 vector<int> topologicalSort()
 65 {
 66     seen = vector<int>(26, 0);
 67     for (int i = 0; i < vvmap.size(); i++) {
 68         //记录需要dfs的索引
 69         if (seen[vvmap[i].first] == 0)
 70             seen[vvmap[i].first] =1;
 71         if (seen[vvmap[i].second] == 0)
 72             seen[vvmap[i].second] = 1;
 73     }
 74     order.clear();
 75     for (int i = 0; i <  26; i++) {
 76         if (seen[i] == 1) 
 77             dfs(i);
 78     }
 79 
 80     reverse(order.begin(), order.end());
 81 
 82     for (int i = 0; i < order.size(); i++) {
 83         for (int j = i+1; j < order.size(); j++) {
 84             if (find(vvmap.begin(), vvmap.end(), pair<int, int>(order[j], order[i])) != vvmap.end())
 85             {
 86                 return vector<int>();
 87             }
 88         }
 89     }
 90     return order;
 91 }
 92 
 93 
 94 int main()
 95 {
 96     cin >> n;
 97 
 98     while (n--) {
 99         int m;
100         vvmap.clear();
101         cin >> m;
102         vector<string> vs;
103         for (int i = 0; i < m; i++) {
104             string s;
105             cin >> s;
106             vs.push_back(s);
107         }
108 
109         for (int i = 0; i < vs.size()-1; i++) {
110             Compare(vs[i], vs[i + 1]);
111         }
112 
113         vector<int> ans = topologicalSort();
114         if (ans.empty()) {
115             cout << "INVALID HYPOTHESIS" << endl;
116         }
117         else {
118             for (int i = 0; i < 26; i++) {
119                 if (find(ans.begin(), ans.end(), i) == ans.end()) {
120                     ans.push_back(i);
121                 }
122             }
123 
124             for (int i = 0; i < ans.size(); i++) {
125                 cout << (char)(ans[i] + 'a');
126             }
127             cout << endl;
128         }
129     }
130 
131 }
View Code
复制代码

 

posted on   itdef  阅读(405)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示