https://www.acmicpc.net/problem/21610
21610번: 마법사 상어와 비바라기
마법사 상어는 파이어볼, 토네이도, 파이어스톰, 물복사버그 마법을 할 수 있다. 오늘 새로 배운 마법은 비바라기이다. 비바라기를 시전하면 하늘에 비구름을 만들 수 있다. 오늘은 비바라기
www.acmicpc.net
구현 문제다. 문제를 잘못 이해하여 많은 시간을 허비했던 문제. 항상 느끼지만 집중해서 글을 읽는 점이 부족한 것 같다.
실수했던 부분은 구름이 생성될 때 해당 바구니의 물은 2씩 사라지지만, 해당 구름이 비를 내릴 때에는 1씩 내린다는 점이다.
풀이
입력범위가 크진 않지만 시간제한이 1초로 제한되어있고 구름이 이동하면서 비를 내리는 게 아니라 이동한 후에 비를 내리기에 구름의 이동을 한 번에 계산하여 처리하도록 접근했다. 구름 배열 cloud: [(Int, Int)] 를 생성하여 구름을 담아내고, 구름이 소멸할 때 구름이 있던 자리를 확인하는 visited: [[Bool]] 배열을 사용하여 물 복사 부분을 처리하였다.
정답 코드
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
let line = readLine()!.split(separator: " ").map{Int($0)!} | |
let n = line[0] | |
let m = line[1] | |
var map = Array(repeating: Array(repeating: 0, count: n), count: n) | |
for i in 0..<n{ | |
let line = readLine()!.split(separator: " ").map{Int($0)!} | |
for k in 0..<n{ | |
map[i][k] = line[k] | |
} | |
} | |
var clouds = [(x:Int,y:Int)]() | |
clouds.append((n-1,0)) | |
clouds.append((n-1,1)) | |
clouds.append((n-2,0)) | |
clouds.append((n-2,1)) | |
let dx = [0,-1,-1,-1,0,1,1,1] | |
let dy = [-1,-1,0,1,1,1,0,-1] | |
for _ in 0..<m{ | |
var visited = Array(repeating: Array(repeating: false, count: n), count: n) | |
let line = readLine()!.split(separator: " ").map{Int($0)!} | |
let direction = line[0] - 1 | |
let distanse = line[1] | |
//구름이동, 비내림 | |
for i in 0..<clouds.count{ | |
clouds[i].x += (dx[direction]*distanse)%n | |
clouds[i].y += (dy[direction]*distanse)%n | |
if clouds[i].x < 0{ | |
clouds[i].x += n | |
}else if clouds[i].x >= n{ | |
clouds[i].x -= n | |
} | |
if clouds[i].y < 0{ | |
clouds[i].y += n | |
}else if clouds[i].y >= n{ | |
clouds[i].y -= n | |
} | |
let nx = clouds[i].x | |
let ny = clouds[i].y | |
map[nx][ny] += 1 | |
} | |
//물복사버그 | |
for _ in 0..<clouds.count{ | |
let cloud = clouds.removeLast() | |
let x = cloud.x | |
let y = cloud.y | |
for i in stride(from: 1, to: 8, by: +2){ | |
let nx = x+dx[i] | |
let ny = y+dy[i] | |
if nx<0 || nx>=n || ny<0 || ny>=n{ continue } | |
if map[nx][ny]>0{ map[x][y]+=1 } | |
} | |
visited[x][y] = true | |
} | |
//구름생성 | |
for i in 0..<n{ | |
for k in 0..<n{ | |
if map[i][k]>1 && !visited[i][k]{ | |
map[i][k] -= 2 | |
clouds.append((i,k)) | |
} | |
} | |
} | |
} | |
var ans = 0 | |
for m in map{ | |
ans += m.reduce(0, +) | |
} | |
print(ans) |

'Problem Solving > BOJ' 카테고리의 다른 글
[15685] 드래곤 커브 (0) | 2022.11.15 |
---|---|
[14500] 테트로미노 (0) | 2022.11.14 |
[14499] 주사위 굴리기 (0) | 2022.11.10 |
[21608] 상어 초등학교 (0) | 2022.11.09 |
[14891] 톱니바퀴 (0) | 2022.11.09 |