일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 너무 어렵다
- 패스트파이브
- 스택
- 자바
- 중첩네비게이션
- media3 transformer
- MVVM
- Kotlin
- innernavigation
- Stack
- parentfragment
- 패파
- 싱글액티비티
- SAA
- fragmentcontainer
- 파이썬
- 코틀린
- 안드로이드
- childfragment
- 알고리즘
- 사무실
- 내부프레그먼트
- rxandroid
- media3
- 백준
- Android
- 재밌긴함
- 후기
- 아키텍쳐
- 공유오피스
삽질도사
[백준] 1113번 수영장만들기 코틀린 본문
https://www.acmicpc.net/problem/1113
1113번: 수영장 만들기
지민이는 수영장을 만들려고 한다. 수영장을 만들 곳의 크기는 N*M이고, 각 칸은 직육면체이다. 따라서, 각 칸의 직육면체의 높이가 쓰여 있는 다음과 같은 땅을 생각할 수 있다. 16661 61116 16661 이
www.acmicpc.net
처음 접근법: 완탐으로 4방향에 대해서 한방향씩 끝까지 탐색한다고 생각하고 각각의 타일에서 한번 더 2방향(내가 온 방향 및 그 반대 제외)을 끝까지 탐색해서 물이 세는지 확인, 4방향 각각의 최대값을 구하고 그 중에서 최소값이 시작타일의 높이보다 크다면 뺀 값이 물을 채울 수 있다는 아이디어 (틀림) -> 계속 물이 세는지 확인한다지만 예외적인 부분(탐색하지 않은 곳에서 물이 샐 수 있음)이 있어서 예제는 다 맞았지만 실패함.
대표반례:
5 5
55515
53121
54445
51115
55555
답: 10
옳은 방법: (다른 블로그 보면서 참고한건데 정말 천재아닌가 싶다...ㅜㅜ) 물이 바깥으로 새어나가는 타일을 찾고 제외하는 것이 이번 문제의 핵심인데 반대로 생각해서 주어진 맵 전체를 둘러싸는 물탑(말 그대로 물로된 탑 높이 1~max까지)이 있다고 생각하고 바깥에서 안쪽으로 물을 집어넣는 것이 핵심이었다.
예를들어, 테두리에 높이 n의 물탑 형성(bfs) -> 맵에서 n보다 낮은 부분을 물탑을 형성하며(미리 만들고해도 상관x) bfs로 탐색 -> n보다 낮은 내부의 타일이 탐색되었다면 물이 샌다는 뜻 -> 물이 샌다는 뜻은 n높이 만큼의 물은 쌓일 수 없다는 것을 의미 -> 해당 타일의 높이를 n으로 만듬. -> n에 대한 bfs가 끝나면 전체탐색으로 n보다 낮은 타일은 물로 층을 하나 채워주고 결과값+1 (map[y][x]++, res++) -> res출력 [이를 n~입력에서 받은 최대높이까지 반복]
한마디로 높이 n위치의 물층을 쌓을 수 있는지 확인하기 위해서 바깥에서부터 물을 n위치에서 집어넣는다는 소리.
package bfs.advanced.b1113
import java.util.LinkedList
val br = System.`in`.bufferedReader()
val getLine get() = br.readLine().split(" ").map { it.toInt() }
var yy = 0
var xx = 0
fun isRange(y:Int,x:Int) = y in 0 until yy+2 && x in 0 until xx+2
lateinit var map: Array<IntArray>
lateinit var visited: Array<BooleanArray>
val que = LinkedList<P>()
var res = 0
var max = 0
val move = listOf(
listOf(0,1),
listOf(0,-1),
listOf(1,0),
listOf(-1,0),
)
data class P(
val y:Int,val x:Int
)
fun bfs(h: Int){
visited = Array(yy+2){ BooleanArray(xx+2) } //독립시행을 위해 초기화
visited[0][0] = true
que.add(P(0,0))
map[0][0] = h
while (que.isNotEmpty()){
val (y,x) = que.poll()
for(r in 0..3){
val dy = y+move[r][0]
val dx = x+move[r][1]
if(isRange(dy,dx) && !visited[dy][dx] && map[dy][dx] < h){ // 해당 높이보다 낮으면 물이 샌다는 뜻
que.add(P(dy,dx))
visited[dy][dx] = true
map[dy][dx] = h //물이 샌다면 bfs 끝나고 완탐할 때 +1하지 않게 h로 높이 고정
}
}
}
}
fun main(){
getLine.let {
yy = it[0]
xx = it[1]
map = Array(yy+2){ IntArray(xx+2) }
for(y in 1 until yy+1){
val p = br.readLine()
for(x in 1 until xx+1) {
max = maxOf(max,p[x-1].toString().toInt())
map[y][x] = p[x-1].toString().toInt()
}
}
for(h in 1..max) {
bfs(h)
for(y in 1 until yy+1)
for(x in 1 until xx+1){
if(map[y][x] < h){ //물이 새지않고 (새었다면 높이가 h이므로 if문에 걸리지도 않음) , 물이 한층 더 쌓일 수 있는 곳은 물을 한층 쌓아준다.
res++
map[y][x]++
}
}
}
println(res)
}
}
'백준' 카테고리의 다른 글
[백준] 15683 감시 삼성 SW 역량 테스트 기출 문제 (2) | 2024.01.25 |
---|---|
[백준] 2504 괄호의 값 자바 (0) | 2021.12.28 |
[백준] 10799 쇠막대기 자바 (0) | 2021.12.27 |
[백준] 빗물 14719 자바 (0) | 2021.03.24 |
[백준] 달력 20207 자바 (0) | 2021.03.23 |