본문 바로가기

백준 PS일지/DFS&BFS

[백준/Swift] 2468번: 안전 영역

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

 

2468번: 안전 영역

재난방재청에서는 많은 비가 내리는 장마철에 대비해서 다음과 같은 일을 계획하고 있다. 먼저 어떤 지역의 높이 정보를 파악한다. 그 다음에 그 지역에 많은 비가 내렸을 때 물에 잠기지 않는

www.acmicpc.net

 

문제 풀기 전에 간단하게 문제를 해석하면서 시작하겠습니다.

 

1. 먼저 어떤 지역의 높이 정보 파악하기!!

       높이는 1~ 100까지 될 수 있습니다. 그런데 지역의 최고 높이 이상인 높이 (or 이하인 높이)부터는 같은 값이 발생됩니다.

       그래서 주어진 지역에서 가장 최고치의 높이와, 가장 최소 높이를 찾아야 합니다.

 

2. 특정한 높이를 포함한 그 이하인 높이의 지점은 전부 물에 잠깁니다!!

 

저는 이 문제를 해결하기 위해 dfs탐색으로 비가 가장 적게 내릴 경우의 높이와 가장 많이 내릴 경우의 높이를 찾고,

 

높이가 가장 작을때~ 클때 까지 포문을 통해 특정 Height에서의 dfs 탐색을 통해 안전가옥이 몇 개인지를 탐색했고, 가장 큰 값인지를 비교해가면서 안전가옥 최대값을 탐색했습니다.

 

---

오늘 알게된 skill!!

 

  • 함수에서 인자값으로 배열을 참조하고 싶은 경우 inout 키워드를 사용한다! 그리고 인자값으로 줄 경우에는 & 연산자를 사용한다!!
  • map함수를 쓸 때, 클로저에서 여러 코드가 있을 경우 return문이 명시되어야 한다!

---

 

참고로 저는 최소 높이 초기값을 3으로 시작했습니다. 어차피 3보다 작은 값이 있으면 해당값으로 바뀔태니까요.

 

제가 작성한 코드입니다.

/**
 * [문제 : 2468](https://www.acmicpc.net/problem/2468)
 * 간단한 코드리뷰.
 *
 * 안전가옥 == land로 지정하고, 값을 받을 때, 최소 h랑 최대 h를 구했습니다.
 * 그리고 비가 내릴 수 있는 최소 h 부터 최대h 까지. 순차적으로 반복하면서, 특정 h에 안전가옥의 크기를 구한 후
 * 안전가옥 최대인지를 구했습니다.
 */
import Foundation
//높이
var h = Int(readLine()!)!
//안전가옥 개수
var safety = 1;
//지역
var land = Array(repeating: [Int](), count: h)
//최소 높이
var minH = 3
//최고 높이
var maxH = 1
// 탐색 방향
var direction = [(-1,0),(1,0),(0,-1),(0,1)]

//지역에 정보 삽입 + maxH or minH 찾기
for i in 0..<h{
    land[i] = readLine()!.split(separator: " ").map{
        if Int(String($0))! < minH{
            minH = Int(String($0))!
        }
        if Int(String($0))! > maxH{
            maxH = Int(String($0))!
        }
        return Int(String($0))!
    }
}
//물에 잠길 수 있는 최소 높이부터 최대 높이까지 순차적으로 탐색
for i in minH...maxH{
    var count = 0;
    var visited = Array(repeating: Array(repeating: false, count: h), count: h)
    
    for y in 0..<h{
        for x in 0..<h{
            if !visited[y][x] && land[y][x] > i{
                dfs(x,y,i, &visited)
                count += 1
            }
        }
    }
    if safety < count {
        safety = count;
    }
}
func dfs(_ x :Int, _ y :Int, _ height:Int, _ visited : inout [[Bool]]){
    for i in direction {
        let nx = x+i.0
        let ny = y+i.1
        if ny < 0 || ny > h - 1 || nx < 0 || nx > h - 1 {
            continue
        }
        if !visited[ny][nx] && land[y][x] > height {
            visited[ny][nx] = true;
            dfs(nx,ny,height, &visited)
        }
    }
}

print(safety)

Come to my Github

 

읽어주셔서 감사합니다!!

 

조언! 지적 정말 감사합니다.. 더 좋고 효율성있는 코드를 배우고 싶습니다.