[백준 17143 - Kotlin] 낚시왕

kldaji·2022년 4월 5일
1

백준

목록 보기
50/76

문제링크

  • 상어가 이동한 후의 좌표를 구하는 것이 가장 어려웠던 문제입니다.
  • 상어가 이동하는 방향에 대한 정보를 dx와 dy라는 리스트에 저장합니다.
  • 상어가 이동하는 방향에 대한 정보를 토대로 현재 상어 좌표 값을 기준으로 이동할 수 있는 거리(여기서는 속력이라고 표현되었네요.)를 계산한 뒤 범위 밖으로 이동했다면 범위 내에서 이동한 거리만큼 남은 거리를 빼주고 방향을 전환시킨 후 범위 내에서 이동한 거리를 저장해줍니다.
  • 이동할 수 있는 거리가 0이 될 때까지 위의 과정을 반복합니다.
import java.io.BufferedReader
import java.io.BufferedWriter

private lateinit var bufferedReader: BufferedReader
private lateinit var bufferedWriter: BufferedWriter

// 1: (-1, 0)
// 2: (1, 0)
// 3: (0, 1)
// 4: (0, -1)
val dx = listOf(0, 0, 0, 1, -1)
val dy = listOf(0, -1, 1, 0, 0)

sealed class Element
data class Shark(var r: Int, var c: Int, val s: Int, var d: Int, val z: Int) : Element()
class Empty : Element()

fun main() {
    bufferedReader = System.`in`.bufferedReader()
    bufferedWriter = System.out.bufferedWriter()

    // 1. get (r, c, m)
    val (r, c, m) = bufferedReader
        .readLine()
        .split(" ")
        .map { it.toInt() }

    // 2. get shark's info
    val board: Array<Array<Element>> = Array(r + 1) { Array(c + 1) { Empty() } }
    val sharks = mutableListOf<Shark>()
    for (i in 0 until m) {
        val (r, c, s, d, z) = bufferedReader
            .readLine()
            .split(" ")
            .map { it.toInt() }
        val shark = Shark(r, c, s, d, z)
        board[r][c] = shark
        sharks.add(shark)
    }

    // 3. catch shark
    var total = 0
    for (i in 1..c) {
        total += catchShark(board, sharks, r, i)
        moveShark(board, sharks, r, c)
    }

    bufferedWriter.write("$total")

    bufferedReader.close()
    bufferedWriter.close()
}

fun catchShark(board: Array<Array<Element>>, sharks: MutableList<Shark>, r: Int, fisher: Int): Int {
    for (i in 1..r) {
        if (board[i][fisher] is Shark) {
            val catchedShark = board[i][fisher] as Shark
            board[i][fisher] = Empty()
            sharks.remove(catchedShark)
            return catchedShark.z
        }
    }
    return 0
}

fun moveShark(board: Array<Array<Element>>, sharks: MutableList<Shark>, r: Int, c: Int) {
    sharks.forEach { shark ->
        var remain = shark.s
        while (remain != 0) {
            val nx = remain * dx[shark.d] + shark.c
            val ny = remain * dy[shark.d] + shark.r
            if (nx > c) {
                remain -= (c - shark.c)
                shark.d = 4
                shark.c = c
            } else if (nx < 1) {
                remain -= (shark.c - 1)
                shark.d = 3
                shark.c = 1
            } else if (ny > r) {
                remain -= (r - shark.r)
                shark.d = 1
                shark.r = r
            } else if (ny < 1) {
                remain -= (shark.r - 1)
                shark.d = 2
                shark.r = 1
            } else {
                remain = 0
                shark.c = nx
                shark.r = ny
            }
        }
    }
    initBoard(board, r, c)
    checkEatenSharks(board, sharks)
}

fun initBoard(board: Array<Array<Element>>, r: Int, c: Int) {
    for (i in 1..r) {
        for (j in 1..c) {
            board[i][j] = Empty()
        }
    }
}

fun checkEatenSharks(board: Array<Array<Element>>, sharks: MutableList<Shark>) {
    val eatenSharks = mutableListOf<Shark>()
    sharks.forEach { shark ->
        if (board[shark.r][shark.c] is Shark) {
            val targetShark = board[shark.r][shark.c] as Shark
            if (targetShark.z < shark.z) {
                board[shark.r][shark.c] = shark
                eatenSharks.add(targetShark)
            } else eatenSharks.add(shark)
        } else board[shark.r][shark.c] = shark
    }
    sharks.removeAll(eatenSharks)
}

profile
다양한 관점에서 다양한 방법으로 문제 해결을 지향하는 안드로이드 개발자 입니다.

0개의 댓글