TIL/알고리즘 공부
백준 3184번 Swift 알고리즘 연습 - 양_BFS
여의도사노비
2023. 2. 20. 12:43
728x90
요즘 계속 알고리즘 스터디를 진행하며 문제를 풀고 있는데...
평소보다 푸는 양이 늘고 면접 + iOS 개발 공부까지 하다보니 도저히 블로그에 기록을 남기기가 쉽지 않다..!
그래도 내가 푸는 몇몇 문제들이 Swift로 블로깅 되어 있지 않은 것을 보고, 그런 문제들 위주로 최대한 기록을 남겨봐야겠다는 생각이 들었다.
이 문제는 전형적인 BFS 문제이다. 정해진 형태의 공간 내에 한칸씩 이동하면서 양과 늑대의 개수를 비교해주면 된다.
이 문제를 풀면서 생각한 논리적 흐름은
- 우선 입력받은 값들을 전부 2차원 배열에 세팅해준다.
- visit 배열을 만들어 내가 확인하고 지나간 곳인지 아닌지를 표시해준다.
- 수직과 수평으로만 이동할 수 있다고 하였으므로 dx, dy를 활용하여 이동 가능 범위를 제한한다.
- 2차원 배열을 setting하는 과정에서 현재 총 양 & 늑대가 몇마리인지 확인한다.
- 양 혹은 늑대가 없는 비어있는 공간은 확인할 필요가 없으므로, 양 혹은 늑대가 있고 아직 방문하지 않은 지역이라면(visit == 0) 들러서 visit 상태를 1로 변경하고 bfs 함수를 시작하여 그 주변의 값들을 전부 확인한다.
- bfs 함수는 현재 받은 위치 정보를 바탕으로 동서남북 이동을 한다. 이때 #이 아닌 지역만 움직일 수 있고 이렇게 움직이면서 양 혹은 늑대를 만나게 되면 각각 숫자를 카운팅해준다.
- 카운팅이 끝나고 비교했을 때 늑대가 양보다 같거나 많으면 전부 늑대, 반대의 경우 양으로 값을 바꿔준다.
- 이 값을 바탕으로 처음 저장해놓은 양 혹은 늑대의 수를 줄여준다.
* 3184번
import Foundation
let input = readLine()!.split(separator: " ").map { Int($0)! }
let r = input[0]
let c = input[1]
var space = [[Character]]()
var visit = [[Int]](repeating: [Int](repeating: 0, count: c), count: r)
var sheep = 0
var wolf = 0
var dx = [1, -1, 0, 0]
var dy = [0, 0, -1, 1]
for _ in 0..<r {
let setting = Array(readLine()!)
for j in 0..<c {
if setting[j] == "o" { sheep += 1 }
if setting[j] == "v" { wolf += 1 }
}
space.append(setting)
}
for i in 0..<r {
for j in 0..<c {
if (space[i][j] == "o" || space[i][j] == "v") && visit[i][j] == 0 {
visit[i][j] = 1
bfs(i, j, space: &space, visit: &visit, sheep: &sheep, wolf: &wolf)
}
}
}
print("\(sheep) \(wolf)")
func bfs(_ x: Int, _ y: Int, space: inout [[Character]], visit: inout [[Int]], sheep: inout Int, wolf: inout Int) {
var move = [[x, y]]
var sameSpaceSheep = 0
var sameSpaceWolf = 0
if space[x][y] == "o" { sameSpaceSheep += 1 }
else if space[x][y] == "v" { sameSpaceWolf += 1 }
while !move.isEmpty {
let curr = move.removeFirst()
let x = curr[0]
let y = curr[1]
for i in 0..<4 {
let nx = x + dx[i]
let ny = y + dy[i]
if nx >= 0 && nx < space.count && ny >= 0 && ny < space[0].count && visit[nx][ny] == 0 && space[nx][ny] != "#" {
if space[nx][ny] == "o" { sameSpaceSheep += 1 }
if space[nx][ny] == "v" { sameSpaceWolf += 1 }
visit[nx][ny] = 1
move.append([nx, ny])
}
}
}
if sameSpaceSheep > 0 && sameSpaceWolf > 0 {
if sameSpaceSheep > sameSpaceWolf { wolf -= sameSpaceWolf }
else { sheep -= sameSpaceSheep }
}
}
정리(Today I Learned)
- BFS 문제를 3개 정도 풀어봤는데 현재까지 풀어본 케이스들은 거의 유사한 것 같다. 약간의 문제별 차이가 존재해서 코드를 짜는데는 여전히 너무 오랜 시간이 걸리지만... BFS 유형의 문제구나라는 확신이 온다면 다른 문제들에 비해서 접근 방식이 명확해질 것 같다. 결국 문제가 어떤 유형의 문제인지 파악하는 힘과 BFS 사용 연습을 많이해서 시간을 줄이는게 최선인 것 같다.