※ 웹 환경에 최적화된 서식이므로 웹 페이지로 열람함을 권장.
보글 게임(링크)
재귀적으로 생각하기
주어지는 단어를 게임판의 알파벳으로 만들 수 있는지 판별하므로 단어의 알파벳 하나와 게임판의 알파벳이 일치하는지 검사하는 작업 조각을 단어의 알파벳 개수만큼 반복해 문제를 해결한다. 단어의 맨 앞 알파벳과 현재 게임판 위치의 알파벳을 비교해 일치하면 나머지 글자로 이루어진 단어를 넘기며 재귀 호출한다.
즉, 재귀 함수는 인자로 받는 단어의 첫 알파벳과 게임판의 알파벳이 일치하는지 확인하는 동일한 작업을 반복한다.
재귀 호출에 필요한 입력
찾아야 할 단어와 현재 검사해야 할 게임판의 좌표를 인자로 받는다.
시간 복잡도
시간 안에 동작하는지 확인하기 위해 최악의 경우를 고려해보자. 길이가 n 인 단어가 주어질 때 마지막 글자를 제외한 나머지 (n - 1) 개의 글자가 일치한다면 (n - 1) 번 동안 이웃한 여덟 개의 칸을 계속 검사하게 된다. 즉, 최악의 경우 O(8^n) 의 시간 복잡도를 가진다.
#include <iostream>
#include <vector>
#include <string>
#define BOARD_WIDTH 5
#define BOARD_HEIGHT 5
using namespace std;
vector<vector<char>> board = {
{'n', 'n', 'n', 'n', 's'},
{'n', 'e', 'e', 'e', 'n'},
{'n', 'e', 'y', 'e', 'n'},
{'n', 'e', 'e', 'e', 'n'},
{'n', 'n', 'n', 'n', 'n'}
};
// 인접한 8 개 좌표의 상대적 위치.
const int directions[8][2] = {
{-1, -1}, {-1, 0}, {-1, 1}, {0, -1},
{0, 1}, {1, -1}, {1, 0}, {1, 1}
};
bool boggle(string word, int yPos, int xPos) {
// 인자로 받는 좌표가 게임판을 넘어가는지 확인.
if (yPos < 0 || BOARD_HEIGHT <= yPos || xPos < 0 || BOARD_WIDTH <= xPos)
return false;
if (board[yPos][xPos] != word[0]) return false;
if (word.length() == 1) return true;
// 현재 좌표에서 인접한 8 개의 좌표로 확산.
for (int next = 0; next < 8; ++next) {
int nextY = yPos + directions[next][0];
int nextX = xPos + directions[next][1];
if (boggle(word.substr(1), nextY, nextX) == true) return true;
}
return false;
}
int main() {
string word = "yes";
// 'y' is at (2, 2) in the board.
if (boggle(word, 2, 2)) {
cout << "Success";
} else {
cout << "Failure";
}
cout << endl;
return 0;
}
'문제 해결 알고리즘 기초 > 완전 탐색' 카테고리의 다른 글
[알고스팟] 여행하는 외판원 문제 - 완전 탐색, 재귀 (0) | 2020.08.04 |
---|---|
[알고스팟] 게임판 덮기 - 완전 탐색, 재귀 (0) | 2020.07.31 |
[알고스팟] 소풍 - 완전 탐색, 재귀 (0) | 2020.07.30 |
완전 탐색으로 n 개 중 r 개 고르기 (조합) (0) | 2020.07.21 |
완전 탐색 알고리즘에 대해서 (0) | 2020.07.21 |