알고리즘

프로그래머스 - 리코쳇 로봇

최데브 2024. 8. 11. 16:20

상하좌우로 움직일 수 있고 최단거리를 찾는 문제여서 bfs 를 떠올렸다.

import java.util.*
class Solution {
    var dx = listOf(-1,1,0,0)
    var dy = listOf(0,0,-1,1)  
    var n = 0
    var m = 0
    fun solution(board: Array<String>): Int {
        var answer: Int = 0
        var startRobot : Moving? = null
        var goal : Moving? = null
        n = board.size
        m = board[0].length
        
       for(i in 0 .. board.size-1){
            for(j in 0 .. board[0].length-1){
                if(board[i][j] == 'R'){
                    startRobot = Moving(i , j , 0)
                }
                if(board[i][j] == 'G'){
                    goal = Moving(i , j , 0)
                }
            }
       }
    
       answer = bfs(board , startRobot!! , goal!!)
        
        
        
        return answer
    }
    
    fun bfs(board: Array<String>, start : Moving , goal : Moving) : Int{
        //시작점도 알고 있어야한다.
        //goal 이 되면 멈춰야하고
        var q : Queue<Moving> = LinkedList()
        val visited = Array(n) { BooleanArray(m) }
        q.add(start)// 시작점을 q에 먼저 넣어준다.
        while(q.isNotEmpty()){
            var mv = q.poll()
            if(mv.x == goal.x && mv.y == goal.y  ){
                return mv.depth
            }
            
            for(i in 0 .. 3){
               var nx = mv.x
               var ny = mv.y
                
               while(safeRange(nx,ny) && board[nx][ny] != 'D'){
                   nx += dx[i]
                   ny += dy[i]
               }
               
               //장애물을 만났으면 바로 직전의 위치로 옮겨야한다.
                nx -= dx[i]
                ny -= dy[i]
               
               if(safeRange(nx,ny) && (visited[nx][ny] == true || nx == mv.x && ny == mv.y)) continue
                visited[nx][ny] = true
               q.add(Moving(nx,ny,mv.depth+1))
            }
            
        }
        return -1
    }
    
    fun safeRange(xIndex : Int, yIndex : Int) : Boolean{
        return (xIndex >=0 && yIndex >=0) && (xIndex< n && yIndex < m)
    }
    
    
    
    data class Moving(
        val x : Int,
        val y : Int,
        val depth : Int
    )
}
반응형