본문 바로가기
Algorithm and PS/백준(Kotlin)

백준 - 21610 마법사 상어와 비바라기 (코틀린)

by ESHC 2022. 4. 14.

[문제]

https://www.acmicpc.net/problem/21610

 

21610번: 마법사 상어와 비바라기

마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기

www.acmicpc.net

[풀이]

구현 문제이기 때문에 문제에 따라 적절하게 코드를 작성해야 한다.

만들어진 구름을 담는 연결리스트와 만들어진 구름의 위치를 저장하는 2차원 배열을 이용한다. 가장 처음의 구름의 위치를 연결리스트에 담는다.

이후에 입력 받은 이동 정보를 통해 구름을 이동하고, 비를 내리고, 물을 주고, 다시 구름을 만드는 작업을 반복해준다.

구름을 이동하는 작업은 이동 방향과 거리를 계산하여 격자를 넘어가면 격자의 크기만큼 더하거나 빼줘서 격자안에서만 이동하도록 구름을 이동하고 이동한 구름의 위치를 2차원 배열에 체크해준다.

이동한 구름의 해당하는 바구니 좌표에 1씩 물을 증가시켜주고, 대각선 방향에 있는 바구니를 이용하여 물이 있는 바구니 수만큼 바구니 좌표에 더해주는 작업을 한다.

격자의 모든 좌표에 대해 만약 이전 작업에서 구름이 만들어진 좌표라면 체크를 해제하고 넘어가고 구름이 만들어지지 않은 좌표이면서 바구니에 든 물의 양이 2 이상이면 구름의 연결리스트에 저장해준다.

위의 작업을 반복하고 각 좌표의 물의 양을 더해주고 출력한다.

[코드]

import java.util.*

private var n = 0
private var m = 0
private lateinit var arr : Array<IntArray>
private val dx = listOf(0,-1,-1,-1,0,1,1,1)
private val dy = listOf(-1,-1,0,1,1,1,0,-1)
private lateinit var clouds : LinkedList<Pair<Int,Int>>
private lateinit var cloudChecks : Array<BooleanArray>
fun main() {
    val br = System.`in`.bufferedReader()
    br.readLine().split(" ").map { it.toInt() }.apply {
        n = this[0]
        m = this[1]
    }
    arr = Array(n){ IntArray(n) }
    cloudChecks = Array(n){ BooleanArray(n) }
    repeat(n){
        arr[it] = br.readLine().split(" ").map { it.toInt() }.toIntArray()
    }
    clouds = LinkedList()
    initClouds()
    for(i in 0 until m){
        val (d,s) = br.readLine().split(" ").map { it.toInt() }
        moveClouds(d,s)
        rainAndWater()
        makeClouds()
    }
    var result = 0
    for(i in 0 until n){
        for(j in 0 until n){
            result += arr[i][j]
        }
    }
    println(result)
}
private fun moveClouds(d:Int,s:Int){
    for(i in 0 until clouds.size){
        val (x,y) = clouds.pollFirst()
        var nx = x + dx[d-1]*(s%n)
        var ny = y + dy[d-1]*(s%n)
        if(nx>= n) nx -= n
        if(ny>= n) ny -= n
        if(nx<0) nx += n
        if(ny<0) ny += n
        cloudChecks[nx][ny] = true
        clouds.addLast(Pair(nx,ny))
    }
}
private fun rainAndWater(){
    for(i in 0 until clouds.size){
        val (x,y) = clouds.pollFirst()
        arr[x][y] += 1
        clouds.addLast(Pair(x,y))
    }
    for(j in 0 until clouds.size){
        val (x,y) = clouds.pollFirst()
        var cnt = 0
        for(i in 1 .. 7 step 2){
            val nx = x + dx[i]
            val ny = y + dy[i]
            if(nx < 0 || ny < 0 || nx >= n || ny >= n) continue
            if(arr[nx][ny] > 0) cnt += 1
        }
        arr[x][y] += cnt
    }
}
private fun makeClouds(){
    for(i in 0 until n){
        for(j in 0 until n){
            if(cloudChecks[i][j]){
                cloudChecks[i][j] = false
            }
            else if(arr[i][j]>= 2) {
                clouds.add(Pair(i, j))
                arr[i][j] -= 2
            }
        }
    }
}
private fun initClouds(){
    clouds.add(Pair(n-1,0))
    clouds.add(Pair(n-2,0))
    clouds.add(Pair(n-1,1))
    clouds.add(Pair(n-2,1))
}

 

댓글