백준

[백준][Kotlin]2251번 물통

끝까지 처음처럼 2023. 4. 1. 12:35
728x90

해당 문제는 진행 할 수 있는 경우는 총 6가지가 있음을 알고, 그래프를 그리는 시점으로 보면 작성 할 수 있는 문제였습니다. 

A,B,C 물통으로 진행 할 수 있는 방법은 AB,AC,BA,BC,CA,CB으로 6개 입니다. 그렇다면 이것을 배열로 만들었을 경우

주는 통(0,0,1,1,2,2) 받는 통 (1,2,0,2,0,1) 이며,  이는 반복문을 통하여 추후 모든 진행 방향을 간단히 확인 할 수 있습니다.

 

그리고 A가 비어 있을 때 세 번째 물통의 용량을 구하기 위하여 세번째 물통의 최대 용량+1의 사이즈를 가진 Boolean 배열을 생성하며(해당 배열은 A가 0일 때 C의 값을 저장하기 위한 용도), A,B의 값은 최대 0~200 이 될 수 있으므로 201의 사이즈를 가진 201사이즈의 Boolean 이차원 배열을 생성합니다.(2개만을 한 이유는 물의 총량은 정해져 있어 A,B를 알면 C를 구할 수 있기 때문입니다.) 해당 배열을 생성한 이유는 A,B의 값으로 해당 용량일 때 확인 유무 체크를 하기 위함입니다.

 

위 와 같은 개념과 BFS를 이용하여 코드를 작성하면 해당 문제를 작성 할 수 있습니다.

 

하기는 제출한 코드와 제출 결과 입니다.

import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.InputStreamReader
import java.io.OutputStreamWriter
import java.util.*

var start = intArrayOf(0,0,1,1,2,2)
var end = intArrayOf(1,2,0,2,0,1)
lateinit var arr: IntArray // 물의 양 저장 목적
var answer = BooleanArray(201) // 기본 false 결과값 저장 배열(C의 양에 해당하는 인덱스 true 처리)
var visit = Array(201,{BooleanArray(201)}) // a와b의 물의 양에 따른 방문체크

fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    var bw = BufferedWriter(OutputStreamWriter(System.out))
    var st = StringTokenizer(br.readLine())
    arr = intArrayOf(st.nextToken().toInt(),st.nextToken().toInt(),st.nextToken().toInt())

    bfs()

    for(i in 0 .. answer.size-1){
        if(answer[i]) bw.append("$i ")
    }

    bw.flush()
    bw.close()

}

fun bfs(){
    visit[0][0] = true
    answer[arr[2]] = true

    var dq = ArrayDeque<Info>() // a와b의 물의 양 저장
    dq.add(Info(0,0))

    while(!dq.isEmpty()){
        val now = dq.poll()
        val a = now.A
        val b = now.B
        val c = arr[2]-a-b

        for(i in 0 .. 5){
            var temp = intArrayOf(a,b,c)
            temp[end[i]] += temp[start[i]]
            temp[start[i]] = 0
            if(temp[end[i]] > arr[end[i]]){ // 물이 넘쳤을 경우
                temp[start[i]] = temp[end[i]] - arr[end[i]]
                temp[end[i]] = arr[end[i]]
            }
            if(!visit[temp[0]][temp[1]]){
                visit[temp[0]][temp[1]] = true
                dq.add(Info(temp[0],temp[1]))
                if(temp[0].equals(0)){
                    answer[temp[2]] = true
                }
            }
        }

    }

}

data class Info(
    val A: Int,
    val B: Int
)