백준 28015번
https://www.acmicpc.net/problem/28015
간단한 구현 그리디 문제이다.
덧칠이 가능하고, 가로 방향으로 칠할 수 있다가 이 문제의 핵심이다.
import java.io.*
import java.util.*
// input
private lateinit var br: BufferedReader
// variables
private var N = 0
private var M = 0
private var ans = 0
// 덧칠하면서 만난 다른 색깔
private var map = Array(101) { IntArray(101) }
fun main() {
br = BufferedReader(InputStreamReader(System.`in`))
val bw = BufferedWriter(OutputStreamWriter(System.out))
val sb = StringBuilder()
input()
val list: MutableList<Int> = ArrayList()
for (i in 0 until N) {
for (j in 0 until M) {
if (map[i][j] != 0) {
list.add(map[i][j])
} else if (map[i][j] == 0 && list.isNotEmpty()) {
// 리스트에서 1과 2가 모두 동시에 포함되어 있는지를 확인
if (list.contains(2) && list.contains(1)) {
// 1과 2가 동시에 있다면, 어떤 걸로 칠하고 덧칠했을 때, 가장 적은 횟수로 가능한지 확인해야 됨
// 적은 횟수로 덧칠할 수 있는 색깔을 구하고, 처음 칠하는 색상을 위해 붓질 한번 더하기
ans += check(list) + 1
} else {
// 1과 2가 동시에 있지 않다면, 굳이 최솟값을 구할 필요가 없다.
ans += 1
}
list.clear()
}
}
// 0을 만나지 못하고 끝났을 경우 고려
if (list.contains(2) && list.contains(1)) {
ans += check(list) + 1
} else if (list.isNotEmpty()) {
// 1과 2가 동시에 있지 않다면, 굳이 최솟값을 구할 필요가 없다.
ans += 1
}
list.clear()
}
sb.append(ans)
bw.write(sb.toString())
bw.close()
} // End of main
private fun check(list: MutableList<Int>): Int {
var oneColor = 0
var twoColor = 0
var preColor = list[0]
if (preColor == 1) {
oneColor = 1
} else {
twoColor = 1
}
var nowColor = -1
val size = list.size
for (i in 1 until size) {
nowColor = list[i]
if (preColor != nowColor) {
if (nowColor == 1) {
oneColor++
} else {
twoColor++
}
} else continue
preColor = nowColor
}
return Math.min(oneColor, twoColor)
} // End of check
private fun input() {
var st = StringTokenizer(br.readLine())
N = st.nextToken().toInt()
M = st.nextToken().toInt()
for (i in 0 until N) {
st = StringTokenizer(br.readLine())
for (j in 0 until M) {
map[i][j] = st.nextToken().toInt()
}
}
} // End of input