두 개의 방문리스트 생성
ArrayList로 변경하여 사용하면 좋겠다
graph를 forEachIndexed로 돌면서 해당 list도 forEachIndex로 돌린다
방문값이 false인 경우를 만나면 구역을 +1 한다
이후 네 방향으로 bfs를 돌려 같은 구역인지 확인다.
적록색약인 경우는 G==R을 이용해서 확인한다.
G -> R로 교체하는 방법도 존재
import java.io.BufferedReader
import java.io.InputStreamReader
val br = BufferedReader(InputStreamReader(System.`in`))
fun main() {
val graph = mutableListOf<MutableList<String>>()
val N = br.readLine().toInt()
repeat(N) {
graph.add(br.readLine().map{ it.toString() }.toMutableList())
}
var visited = graph.map { list ->
list.map { false }.toMutableList()
}.toMutableList()
var visitedRG = graph.map { list ->
list.map { false }.toMutableList()
}.toMutableList()
var count = 0
var countRG = 0
graph.forEachIndexed {row, list ->
list.forEachIndexed { col, element ->
if (!visited[row][col]) {
count++
val stack = mutableListOf<Pos>(Pos(row, col))
while (stack.isNotEmpty()) {
val pos = stack.removeFirstOrNull() ?: continue
if (pos.x < 0 || pos.x > graph.size-1 || pos.y < 0 || pos.y > graph.size-1) continue
if (!visited[pos.y][pos.x] && graph[pos.y][pos.x] == element) {
visited[pos.y][pos.x] = true
stack.addAll(getFourDirections(pos.y, pos.x))
}
}
}
if (!visitedRG[row][col]) {
countRG++
val stack = mutableListOf<Pos>(Pos(row, col))
while (stack.isNotEmpty()) {
val pos = stack.removeFirstOrNull() ?: continue
// 여기서 거르고
if (pos.x < 0 || pos.x > graph.size-1 || pos.y < 0 || pos.y > graph.size-1) continue
if (element == "B") {
//걸러진걸로 조회하고
if (!visitedRG[pos.y][pos.x] && graph[pos.y][pos.x] == "B") {
visitedRG[pos.y][pos.x] = true
//무지성으로 추가하면
stack.addAll(getFourDirections(pos.y, pos.x))
}
} else {
if (!visitedRG[pos.y][pos.x] && (graph[pos.y][pos.x] == "G" || graph[pos.y][pos.x] == "R" )) {
visitedRG[pos.y][pos.x] = true
stack.addAll(getFourDirections(pos.y, pos.x))
}
}
}
}
}
}
println("$count $countRG")
}
fun getFourDirections(y:Int, x: Int): List<Pos> {
val dx = listOf(-1,1,0,0)
val dy = listOf(0,0,-1,1)
return dx.mapIndexed { idx, it ->
(Pos(y+dy[idx],x + it))
}
}
data class Pos(val y: Int, val x: Int)