문제 링크입니다: https://www.acmicpc.net/problem/2186
2186번: 문자판
첫째 줄에 N(1 ≤ N ≤ 100), M(1 ≤ M ≤ 100), K(1 ≤ K ≤ 5)가 주어진다. 다음 N개의 줄에는 M개의 알파벳 대문자가 주어지는데, 이는 N×M 크기의 문자판을 나타낸다. 다음 줄에는 1자 이상 80자 이하의 영단어가 주어진다. 모든 문자들은 알파벳 대문자이며, 공백 없이 주어진다.
www.acmicpc.net
DFS + DP 문제였습니다.
처음에는 DFS 알고리즘만 적용했는데 시간초과가 발생했습니다.
(최대 100 * 100 보드판에 최대 80 길이의 문자열을 찾아야하고 visited 배열을 사용할 수 없기 때문에 당연히 TLE가 발생합니다.)
따라서, 각 칸과 목표 문자열의 인덱스를 기준으로 캐싱하여 DP를 적용하면 시간초과를 방지할 수 있습니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
#include <vector> | |
#include <cstring> | |
using namespace std; | |
const int MAX = 100; | |
const int MAX_LENGTH = 80; | |
typedef struct | |
{ | |
int y, x; | |
}Dir; | |
Dir moveDir[4] = { { 1, 0 },{ -1, 0 },{ 0, 1 },{ 0, -1 } }; | |
int N, M, K; | |
int result; | |
string target; | |
string board[MAX]; | |
int cache[MAX][MAX][MAX_LENGTH]; | |
int func(int y, int x, int idx) | |
{ | |
int &result = cache[y][x][idx]; | |
if (result != -1) | |
{ | |
return result; | |
} | |
if (idx == target.length()) | |
{ | |
return 1; | |
} | |
result = 0; | |
for (int k = 0; k < 4; k++) | |
{ | |
int tempY = y; | |
int tempX = x; | |
for (int i = 0; i < K; i++) | |
{ | |
int nextY = tempY + moveDir[k].y; | |
int nextX = tempX + moveDir[k].x; | |
if (nextY < 0 || nextY >= N || nextX < 0 || nextX > M) | |
{ | |
break; | |
} | |
if (board[nextY][nextX] == target[idx]) | |
{ | |
result += func(nextY, nextX, idx + 1); | |
} | |
tempY = nextY; | |
tempX = nextX; | |
} | |
} | |
return result; | |
} | |
int main(void) | |
{ | |
ios_base::sync_with_stdio(0); | |
cin.tie(0); | |
cin >> N >> M >> K; | |
for (int i = 0; i < N; i++) | |
{ | |
cin >> board[i]; | |
} | |
cin >> target; | |
vector<pair<int, int>> start; | |
for (int i = 0; i < N; i++) | |
{ | |
for (int j = 0; j < M; j++) | |
{ | |
if (board[i][j] == target[0]) | |
{ | |
start.push_back({ i, j }); | |
} | |
} | |
} | |
memset(cache, -1, sizeof(cache)); | |
for (int i = 0; i < start.size(); i++) | |
{ | |
int y = start[i].first; | |
int x = start[i].second; | |
result += func(y, x, 1); | |
} | |
cout << result << "\n"; | |
return 0; | |
} |


개발환경:Visual Studio 2017
지적, 조언, 질문 환영입니다! 댓글 남겨주세요~
반응형
'알고리즘 > BOJ' 카테고리의 다른 글
백준 2957번 이진 탐색 트리 (0) | 2019.10.08 |
---|---|
백준 2933번 미네랄 (0) | 2019.10.07 |
백준 5635번 생일 (2) | 2019.10.02 |
백준 6118번 숨바꼭질 (0) | 2019.09.29 |
백준 1516번 게임 개발 (0) | 2019.09.29 |