본문 바로가기
알고리즘 문제 풀이/백준

백준 1987 알파벳 Kotlin (dfs)

by 옹구스투스 2021. 12. 22.
반응형

문제 출처 : https://www.acmicpc.net/problem/1987

 

1987번: 알파벳

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

www.acmicpc.net

문제

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

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

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

입력

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

출력

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

알고리즘 분류

풀이

간단한 dfs 문제이다.

2차원 그래프의 모습이지만, 방문 체크는 그래프의 좌표가 아닌 '알파벳'으로 한다.

따라서 visited 배열의 크기는 26이다.

방문 체크를 그래프의 좌표가 아닌 알파벳으로 하는 이유는,

같은 알파벳을 두 번 방문할 수 없으니 알파벳으로 방문 체크해야 하는 것이고,

어떤 좌표에서 'A'를 방문했을 때, 다른 좌표에서 'A'를 더 이상 방문하지 못하게 하는 것을 방지하기 위해 dfs가 다음 칸을 방문하고 다시 돌아올 때 visited[i] = false처리를 해준다.

이로써 한 dfs의 줄기에서 방문한 알파벳들이 다른 dfs의 줄기에 영향을 끼치지 않는다.

 

코드

val br = System.`in`.bufferedReader()
val dirXY = arrayOf(arrayOf(0,1),arrayOf(0,-1),arrayOf(1,0),arrayOf(-1,0))
var answer=0
val visited = BooleanArray(26)
fun dfs(r : Int, c: Int, cnt : Int, R: Int, C : Int, graph : Array<String>){

    answer = answer.coerceAtLeast(cnt)

    for(i in 0 until 4){
        val nr = r+dirXY[i][0]
        val nc = c+dirXY[i][1]
        if(nr !in 0 until R || nc !in 0 until C) continue
        if(visited[graph[nr][nc]-'A'])continue
        visited[graph[nr][nc]-'A']=true
        dfs(nr,nc,cnt+1,R,C,graph)
        visited[graph[nr][nc]-'A']=false
    }
}

fun main() = with(System.out.bufferedWriter()){
    val (r,c) = br.readLine().split(' ').map{it.toInt()}
    val graph = Array(r){br.readLine()}
    visited[graph[0][0]-'A']=true
    dfs(0,0,1,r,c,graph)
    write("$answer")
    close()
}
반응형

댓글