문제
세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸 (1행 1열) 에는 말이 놓여 있다.
말은 상하좌우로 인접한 네 칸 중의 한 칸으로 이동할 수 있는데, 새로 이동한 칸에 적혀 있는 알파벳은 지금까지 지나온 모든 칸에 적혀 있는 알파벳과는 달라야 한다. 즉, 같은 알파벳이 적힌 칸을 두 번 지날 수 없다.
좌측 상단에서 시작해서, 말이 최대한 몇 칸을 지날 수 있는지를 구하는 프로그램을 작성하시오. 말이 지나는 칸은 좌측 상단의 칸도 포함된다.
시간 제한: 2초
메모리 제한: 256MB
입력
첫째 줄에R과C가 빈칸을 사이에 두고 주어진다. (1≤R, C≤20) 둘째 줄부터 R개의 줄에 걸쳐서 보드에 적혀 있는 C개의 대문자 알파벳들이 빈칸 없이 주어진다.
출력
첫째 줄에 말이 지날 수 있는 최대의 칸 수를 출력한다.
예제 입력 | 예제 출력 |
2 4
CAAB
ADCB | 3 |
3 6
HFDFFB
AJHGDH
DGAGEH | 6 |
5 5
IEFCJ
FHFKC
FFALF
HFGCF
HMCHH | 10 |
풀이
네 방향 중 갈 수 있는 방향으로 반복해서 이동했을 때 이동횟수의 최댓값을 구해야 한다.
노드 방문을 체크하는것이 아닌 알파벳을 체크해야 해서 26사이즈의 visited bool형 배열을 만들었고, 문자 뺄셈을 통해 정수형으로 변환하여 인덱스처럼 사용하였다.
BFS를 사용하면 쉽게 풀 수 있는 문제이다.
코드
#include <iostream> #include <unordered_map> #include <vector> using namespace std; int row, col; int dx[] = { -1, 0, 1, 0 }; int dy[] = { 0, 1, 0, -1 }; int Recursive(const vector<vector<char>>& matrix, int x, int y, vector<bool>& visited) { visited[matrix[x][y] - 'A'] = true; int result = 1; for(int dir = 0; dir < 4; dir++) { int nx = x + dx[dir]; int ny = y + dy[dir]; if(nx >= 0 && nx < row && ny >= 0 && ny < col && !visited[matrix[nx][ny] - 'A']) { result = max(Recursive(matrix, nx, ny, visited) + 1, result); } } visited[matrix[x][y] - 'A'] = false; return result; } int main(){ ios::sync_with_stdio(false); cin.tie(NULL); cin >> row >> col; vector<bool> visited(26, false); vector<vector<char>> matrix(row, vector<char>(col, '-')); for (int i = 0; i < row; ++i) { string input; cin >> input; for(int j = 0; j < col; ++j) { matrix[i][j] = input[j]; } } cout << Recursive(matrix, 0, 0, visited); }