① 체크인
② 목적지에 도착했는가?
③ 연결된 곳을 순회
④ 갈 수 있는가?
⑤ 간다
⑥ 체크아웃
void search(Node root) {
if (root == null) return;
// 1. root 노드 방문
visit(root);
root.visited = true; // 1-1. 방문한 노드를 표시
// 2. root 노드와 인접한 정점을 모두 방문
for each (Node n in root.adjacent) {
if (n.visited == false) { // 4. 방문하지 않은 정점을 찾는다.
search(n); // 3. root 노드와 인접한 정점 정점을 시작 정점으로 DFS를 시작
}
}
}
남극에 사는 김지민 선생님은 학생들이 되도록이면 많은 단어를 읽을 수 있도록 하려고 한다. 그러나 지구온난화로 인해 얼음이 녹아서 곧 학교가 무너지기 때문에, 김지민은 K개의 글자를 가르칠 시간 밖에 없다. 김지민이 가르치고 난 후에는, 학생들은 그 K개의 글자로만 이루어진 단어만을 읽을 수 있다. 김지민은 어떤 K개의 글자를 가르쳐야 학생들이 읽을 수 있는 단어의 개수가 최대가 되는지 고민에 빠졌다.
남극언어의 모든 단어는 "anta"로 시작되고, "tica"로 끝난다. 남극언어에 단어는 N개 밖에 없다고 가정한다. 학생들이 읽을 수 있는 단어의 최댓값을 구하는 프로그램을 작성하시오.
첫째 줄에 김지민이 K개의 글자를 가르칠 때, 학생들이 읽을 수 있는 단어 개수의 최댓값을 출력한다.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int N, K;
int num = 0;
bool alphabet[26];
vector<string> words;
void DFS(int index, int selectedCount) {
//1. 체크인=> visited[index] = true, selectedCount
//2. 목적지인가? selectedCount가 k에 도달했는가 => max 갱신
//3. 연결된 곳을 순회 => index +1 ~26
//4. 갈 수 있는가? => visited[next] == false
//5. 간다 => dfs(next)
//6. 체크아웃 => visited[index] = false, selectedCount
if (selectedCount == K) {
bool isRead;
int readCount = 0;
for(int i=0;i<words.size();i++) {
isRead = true;
string temp = words[i];
for(int j=0;j<temp.size();j++) {
if(alphabet[temp[j] - 'a']==false) {
isRead = false;
break;
}
}
if(isRead==true) {
readCount++;
}
}
num = (readCount>=num) ? readCount : num;
}
for(int i=index; i<26; i++) {
if(alphabet[i]==true) {
continue;
}
alphabet[i] = true;
DFS(i, selectedCount+1);
alphabet[i] = false;
}
}
int main() {
cin >> N >> K;
for(int i=0;i<N;i++) {
string s;
cin >> s;
words.push_back(s);
}
if(K<5) {
cout << 0 << endl;
return 0;
}
alphabet['a'-'a'] = true;
alphabet['n'-'a'] = true;
alphabet['t'-'a'] = true;
alphabet['i'-'a'] = true;
alphabet['c'-'a'] = true;
K -= 5;
DFS(0,0);
cout << num << endl;
}
무향 연결 그래프에서 깊이 우선 탐색(DFS)로 탐색하면서 생성된 신장 트리(Spanning Tree)