문제 :
https://www.acmicpc.net/problem/16931
1. 문제 이해하기
- 입력으로 좌, 우(n, m), 그리고 각 칸마다 올려진 블록의 개수를 2차원 배열로 주어진다.
- 총 겉넓이(위, 아래, 앞, 뒤, 좌, 우 넓이) 출력하기
2. 문제 풀이 생각하기
- 먼저 위아래는 (2차원 배열의 행 * 열 * 2), 좌, 우는 (좌의 겉넓이 * 2), 앞, 뒤도 (앞의 겉넓이 * 2) 구하면 된다고 생각했습니다.
- 처음에는 한 방향의 겉넓이를 (각 행 또는 각 열의 가장 큰 값의 합)으로 구하면 된다고 생각했는데 예제 입력 2를 보면 60이 나오는데 안 보이는 부분에서의 넓이를 따로 구해서 더해주어야 한다는 것을 뒤늦게 깨달았습니다.
- 그래서 좌측 겉넓이로 예를 들어보면 열 = 0일 때 겉넓이를 더하고, 열 = 1번째부터는 이전 칸(g[i][j - 1])과 현재 칸(g[i][j])의 높이를 비교해서 현재 칸이 높으면 차이만큼 tmpSum에 더하고 최종적으로 좌, 우 겉넓이 합(tmpSum * 2)을 ans에 더합니다.
총 6군데의 겉넓이를 구해야 하며, 안 보이는 겉넓이를 고려해서 구해야 합니다.
3. 차근차근 구현하기
import Foundation
var matrix = readLine()!.components(separatedBy : " ")
let (n, m) = (Int(matrix[0])!, Int(matrix[1])!)
var g = [[Int]]() // graph
var ans = n * m * 2
for _ in 0..<n {
let line = readLine()!.components(separatedBy : " ").map{Int(String(($0)))!}
g.append(line)
}
// 좌, 우 겉넓이 구하기 -> 좌 겉넓이 * 2
for i in 0..<n {
var tmpSum = 0 // 행별 합
for j in 0..<m {
if j == 0 {
tmpSum += g[i][j]
}
// 현재 개수와 이전 개수를 비교
else if g[i][j - 1] < g[i][j] {
tmpSum += g[i][j] - g[i][j - 1]
}
}
ans += 2 * tmpSum
}
// 앞, 뒤 겉넓이 구하기 -> 앞 겉넓이 * 2
for j in 0..<m {
var tmpSum = 0 // 열별 합
for i in 0..<n {
if i == 0 {
tmpSum += g[i][j]
}
// 현재 개수와 이전 개수를 비교
else if g[i - 1][j] < g[i][j] {
tmpSum += g[i][j] - g[i - 1][j]
}
}
ans += 2 * tmpSum
}
print(ans)
// Test Case
//3 3
//4 1 3
//2 2 2
//2 2 2
//
//답 : 56
//
//3 5
//4 3 1 3 4
//1 1 1 1 1
//1 1 1 1 1
//
//답 : 78
4. 피드백
- '안 보이는 부분을 구해야 한다'는 생각을 빠르게 못해서 아쉬웠고, else if 부분에서 처음에는 g[i][j] < g[i][j + 1] 식의 현재 칸의 겉넓이와 다음 칸의 겉넓이 값을 비교해서 에러가 있었는데 이전 값을 비교해야 된다는 것을 늦게 깨달았습니다.
'Algorithm > Swift' 카테고리의 다른 글
[Programmers] 행렬 테두리 회전하기 (Swift) (0) | 2021.07.10 |
---|---|
[Programmers] 로또의 최고 순위와 최저 순위 (Swift) (0) | 2021.07.10 |
[Programmers] 카카오 인턴십 - 경주로 건설 (Swift) (0) | 2021.07.03 |
[Programmers] 2020 카카오 인턴십 - 보석쇼핑 (Swift) (0) | 2021.07.02 |
[Programmers] 2020 카카오 인턴십 - 수식 최대화 (Swift) (0) | 2021.07.02 |