문제 링크: https://algospot.com/judge/problem/read/DICTIONARY
(출처: 종만북)
임의의 알파벳 순서를 가진 사전 순서대로 정렬된 단어들을 입력받았을 때, 그 사전의 알파벳 우선순위를 출력하고 알파벳 순서에 모순이 있다면 에러 메시지를 출력하는 문제입니다.
단어들을 이용해 graph[26][26]을 만드는데, 이 때 간선 [i][j]는 알파벳 i가 j 앞에 와야됨을 의미합니다. 그래프를 만들 때 인접 단어끼리만 검사하면 됩니다.
그래프를 만든 뒤 DFS를 이용해 위상정렬을 한 뒤, 반환된 순서에서 오른쪽에서 왼쪽으로 가는 간선이 있는지 확인하면 됩니다. 그런 간선이 있으면 알파벳 순서에 모순이 있는 거겠죠.
#pragma GCC optimize ("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
//<i, j> --> 알파벳 i가 j보다 앞에 옴
vector<vector<int> > graph;
// 주어진 단어들로부터 알파벳간의 선후관계 그래프 생성
void makeGraph(const vector<string>& words) {
graph = vector<vector<int> >(26, vector<int>(26, 0));
for (int j = 1; j < words.size(); ++j) {
int i = j - 1, len = min(words[i].size(), words[j].size());
// word[i]가 word[j] 앞에 오는 이유를 찾음
for (int k = 0; k < len; ++k) {
if (words[i][k] != words[j][k]) {
int a = words[i][k] - 'a';
int b = words[j][k] - 'a';
graph[a][b] = 1;
break;
}
}
}
}
vector<int> visited, order;
void dfs(int current) {
visited[current] = 1;
for (int next = 0; next < graph.size(); ++next)
if (graph[current][next] && !visited[next])
dfs(next);
order.push_back(current);
}
// graph를 위상정렬한 결과를 반환
// DAG가 아니라면 빈 벡터 반환
vector<int> topologicalSort() {
int m = graph.size();
visited = vector<int>(m, 0);
order.clear();
for (int i = 0; i < m; ++i)
if (!visited[i])
dfs(i);
reverse(order.begin(), order.end());
// 역방향 간선이 있는 경우 --> DAG가 아님
for (int i = 0; i < m; ++i)
for (int j = i + 1; j < m; ++j)
if (graph[order[j]][order[i]])
return vector<int>();
return order;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<string> words(n);
for (auto& w : words)
cin >> w;
makeGraph(words);
auto orders = topologicalSort();
if (orders.empty()) {
cout << "INVALID HYPOTHESIS\n";
}
else {
for (auto& o : orders)
cout << static_cast<char>(o + 'a');
cout << '\n';
}
}
return 0;
}
반응형
'Online Judge > 알고스팟' 카테고리의 다른 글
[알고스팟][C++] ROUTING: 신호 라우팅 (0) | 2020.06.20 |
---|---|
[알고스팟][C++] WORDCHAIN: 단어 제한 끝말잇기 (0) | 2020.05.17 |
[알고스팟][C++] TRAVERSAL: 트리 순회 순서 변경 (0) | 2020.04.30 |
[알고스팟][C++] ITES: 외계 신호 분석 (0) | 2020.04.27 |
[알고스팟][C++] BRACKETS2: 짝이 맞지 않는 괄호 (0) | 2020.04.26 |