알고스팟 문제 링크: https://www.algospot.com/judge/problem/read/DICTIONARY
algospot.com :: DICTIONARY
고대어 사전 문제 정보 문제 아마추어 고고학자인 일리노이 존스는 시카고 근교에서 고대 문명의 흔적을 찾아냈습니다. 그 흔적 중에는 이 언어의 사전도 포함되어 있었는데, 이 사전에 포함된
www.algospot.com
새롭게 정의된 사전순으로 입력된 단어들을 통해 새로운 사전순의 알파벳 순서를 알아내는 문제이다.
dfs를 이용한 위상 정렬을 사용하면 문제를 풀 수 있다.
dfs를 사용하면 어차피 우선순위가 낮은 알파벳 먼저 order에 push되므로 들어오는 간선이 하나도 없는 정점들을 굳이 먼저 탐색하지 않아도 된다.
#include<iostream> | |
#include<vector> | |
#include<algorithm> | |
using namespace std; | |
// 인접리스트를 위한 이차원 vector adj | |
vector<vector<int>>adj; | |
// 인접리스트 만들기 | |
void makeGraph(vector<string>& words) { | |
adj = vector<vector<int>>(26); | |
// 주어진 차례대로 두개씩 비교 | |
for (int j = 1; j < words.size(); j++) { | |
int i = j - 1; | |
int len = min(words[i].length(), words[j].length()); | |
for (int k = 0; k < len; k++) | |
// 사전순서가 다른 이유가 되는 k번째 문자 | |
if (words[i][k] != words[j][k]) { | |
// 계산하기 쉽게 문자를 정수로 변환 | |
int a = words[i][k] - 'a'; | |
int b = words[j][k] - 'a'; | |
// a가 나타내는 문자가 b가 나타내는 문자보다 우선순위가 높음 | |
adj[a].push_back(b); | |
break; | |
} | |
} | |
} | |
// 탐색 유무, 알파벳 사전 순서 | |
vector<int> seen, order; | |
void dfs(int here) { | |
seen[here] = 1; | |
for (int i = 0; i < adj[here].size(); i++) | |
// 현재 알파벳보다 뒤에 나와야 하는게 있으면 dfs재귀 | |
if (!seen[adj[here][i]]) | |
dfs(adj[here][i]); | |
// 현재 알파벳보다 뒤에 나와야하는 알파벳을 모두 dfs완료했으면 자신도 order.push | |
order.push_back(here); | |
} | |
vector<int> topologicalSort() { | |
int m = adj.size(); | |
seen = vector<int>(m, 0); | |
order.clear(); | |
for (int i = 0; i < m; i++) if (!seen[i]) dfs(i); | |
// dfs를 실행하면 order가 사전순의 역순으로 정렬되 있으므로 뒤집어 준다. | |
reverse(order.begin(), order.end()); | |
for (int i = 0; i < m; i++) | |
for (int j = i + 1; j < m; j++) | |
for(int k=0; k<adj[order[j]].size(); k++) | |
// 자신보다 뒤에 나와야하는 알파벳이 자신보다 먼저 나와야 하면 모순 | |
if (adj[order[j]][k]==order[i]) | |
return vector<int>(); | |
return order; | |
} | |
int main() { | |
int testcase; | |
cin >> testcase; | |
while (testcase--) { | |
int n; | |
cin >> n; | |
vector<string> words(n); | |
for (int i = 0; i < n; i++) | |
cin >> words[i]; | |
makeGraph(words); | |
vector<int> result = topologicalSort(); | |
if (result.empty()) | |
cout << "INVALID HYPOTHESIS" << endl; | |
else { | |
for (int i = 0; i < result.size(); i++) | |
cout << char(result[i] + 'a'); | |
cout << endl; | |
} | |
} | |
} |

댓글을 통한 코드리뷰, 질문, 지적 언제든 환영입니다!
reference: 프로그래밍 대회에서 배우는 알고리즘 문제해결전략2
'Algorithm > algospot' 카테고리의 다른 글
algospot Sorting Game(문제 ID: SORTGAME) c++ (0) | 2021.10.27 |
---|---|
algospot 단어 제한 끝말잇기 (문제 ID: WORDCHAIN) c++ (0) | 2021.10.22 |
algospot 에디터 전쟁 (문제 ID: EDITORWARS) c++ (0) | 2021.10.18 |
algospot 삽입 정렬 시간 재기 (문제 ID: MEASURETIME)c++ (0) | 2021.10.15 |
algospot 족보 탐험 (문제 ID: FAMILYTREE) c++ (0) | 2021.10.14 |