[백준] 1987. 알파벳 (자바 JAVA)

thsamajiki·2024년 3월 3일
0

문제

세로 R칸, 가로 C칸으로 된 표 모양의 보드가 있다. 보드의 각 칸에는 대문자 알파벳이 하나씩 적혀 있고, 좌측 상단 칸(1행 1열)에는 말이 놓여 있다.

말은 상하좌우로 인접한 네 칸 중의 한 칸으로 이동할 수 있는데, 새로 이동한 칸에 적혀 있는 알파벳은 지금까지 지나온 모든 칸에 적혀 있는 알파벳과는 달라야 한다. 즉, 같은 알파벳이 적힌 칸을 두 번 지날 수 없다.

좌측 상단에서 시작해서, 말이 최대한 몇 칸을 지날 수 있는지를 구하는 프로그램을 작성하시오. 말이 지나는 칸은 좌측 상단의 칸도 포함된다.

입력

첫째 줄에 R과 C가 빈칸을 사이에 두고 주어진다. (1 ≤ R, C ≤ 20) 둘째 줄부터
R개의 줄에 걸쳐서 보드에 적혀 있는 C개의 대문자 알파벳들이 빈칸 없이 주어진다.

출력

첫째 줄에 말이 지날 수 있는 최대의 칸 수를 출력한다.

예제 입력 1

2 4
CAAB
ADCB

예제 출력 1

3

예제 입력 2

3 6
HFDFFB
AJHGDH
DGAGEH

예제 출력 2

6

예제 입력 3

5 5
IEFCJ
FHFKC
FFALF
HFGCF
HMCHH

예제 출력 3

10



풀이

이 문제를 어떻게 접근할까 생각하다가 '최대한 몇 칸을 지날 수 있는지'를 읽고서 BFS로 풀어봤는데 BFS로 풀이할게 아니었다.
그 이유는 동시에 같은 레벨의 다른 접점을 접근하기 때문에 만약 레벨 2의 같은 알파벳이 있으면 방문 여부를 파악하기가 힘들다.

그래서 DFS로 풀어야 한다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
    static int R, C, answer = 1;
    static int[] dx = { -1, 0, 1,  0 };
    static int[] dy = {  0, 1, 0, -1 };
    static char[][] board;
    static boolean[] visited;

    public void solution(int x, int y, int count) {
        for (int i = 0; i < 4; i++) {
            int nextX = x + dx[i];
            int nextY = y + dy[i];

            if (nextX < 0 || nextX > R - 1 || nextY < 0 || nextY > C - 1) continue;
            if (!visited[board[nextX][nextY] - 'A']) {
                visited[board[nextX][nextY] - 'A'] = true;
                solution(nextX, nextY, count + 1);
                visited[board[nextX][nextY] - 'A'] = false;
            } else {
                answer = Math.max(answer, count);
            }
        }
    }

    public static void main(String[] args) throws IOException {
        Main main = new Main();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        board = new char[R][C];
        visited = new boolean[26];

        for (int i = 0; i < R; i++) {
            String input = br.readLine();
            for (int j = 0; j < C; j++) {
                board[i][j] = input.charAt(j);
            }
        }

        visited[board[0][0] - 'A'] = true;
        main.solution(0, 0, 1);

        System.out.println(answer);
    }
}
profile
안드로이드 개발자

0개의 댓글