題目: UVa - 200 - Rare Order
題目說明
給一些依據某種字典序排序的字串,求該字典序為何。
Input: 測資裡面有好幾行字串,以 "#"
為終止,字串的順序為升冪排序。
Output: 輸出測資以什麼字典序排序。
解題思路
讀取測資,每次取兩個字串來比較,將比字元 A 大的字元推入 G[0]
表示 A 指向該字元,…,以此類推來建圖,同時使用一個陣列紀錄字元的狀態,因為 DFS 時需要以沒有大於其他字元的為起點,之後使用 DFS 做 Topological sort 即可。
參考解法
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| #include <iostream> #include <algorithm> #include <functional> #include <vector> #include <list>
#define FOR(i, n) for(int i = 0; i < n; ++i) #define LOOP(n) for(int I = 0; I < n; ++I) #define diff(ch) (ch - 'A')
using namespace std;
static auto __ = [] { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); return 0; }();
int main() { string str1, str2; cin >> str1;
int mem[26] = {}; vector<int> G[26];
while (cin >> str2 && str2 != "#") { int l = min(str1.length(), str2.length()); FOR(i, l) { if (!mem[diff(str1[i])]) mem[diff(str1[i])] = 1; if (!mem[diff(str2[i])]) mem[diff(str2[i])] = 1;
if (str1[i] != str2[i]) { G[diff(str1[i])].push_back(diff(str2[i])); mem[diff(str2[i])] = 2; break; } } str1 = str2; }
int visited[26] = {}; list<char> ret;
function<void(int)> dfs = [&](int n) { if (visited[n] == 1) return; visited[n] = 1;
for (auto& i : G[n]) if (visited[i] != 2) dfs(i); visited[n] = 2;
ret.push_front(n + 'A'); };
FOR(i, 26) if (mem[i] == 1) dfs(i);
for (auto& ch : ret) cout << ch; cout << '\n'; }
|
由於依照題目測資建好的圖必為 DAG,所以可以不用判斷碰到環的情況,因此也可以這樣寫。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include <iostream> #include <algorithm> #include <functional> #include <vector> #include <list>
#define FOR(i, n) for(int i = 0; i < n; ++i) #define LOOP(n) for(int I = 0; I < n; ++I) #define diff(ch) (ch - 'A')
using namespace std;
static auto __ = [] { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); return 0; }();
int main() { string str1, str2; cin >> str1;
int mem[26] = {}; vector<int> G[26];
while (cin >> str2 && str2 != "#") { int l = min(str1.length(), str2.length()); FOR(i, l) { if (!mem[diff(str1[i])]) mem[diff(str1[i])] = 1; if (!mem[diff(str2[i])]) mem[diff(str2[i])] = 1;
if (str1[i] != str2[i]) { G[diff(str1[i])].push_back(diff(str2[i])); mem[diff(str2[i])] = 2; break; } } str1 = str2; }
bool visited[26]{}; list<char> ret;
function<void(int)> dfs = [&](int n) { if (visited[n]) return; visited[n] = true; for (auto& i : G[n]) dfs(i); ret.push_front(n + 'A'); };
FOR(i, 26) if (mem[i] == 1) dfs(i);
for (auto& ch : ret) cout << ch; cout << '\n'; }
|
參考資料
[UVa] 200 Rare Order.cpp
UVA 200 /RARE ORDER