https://www.acmicpc.net/problem/14891
풀이과정
해당 문제는 4개의 톱니바퀴가 있으며, 특정 톱니를 시계방향 또는 반시계 방향으로 회전시켰을 때
왼쪽과 오른쪽에 있는 톱니의 맞닿은 부분이 서로 다른 극이면 영향을 받아 회전한 톱니의 반대 방향으로 회전한다.
모든 회전이 끝났을 때 12시 방향의 극에 따라 점수를 계산하고 출력하는 문제이다.
톱니의 극은 배열로 주어지며, 회전을 추적하기 위해 12시 방향을 가리키는 변수를 두어 문제를 해결하였다.
import Foundation
var gear: [[Character]] = Array(repeating: [], count: 5)
var gearPoint = [0,0,0,0,0]
for i in 1...4 {
let input = Array(readLine()!)
gear[i] = input
}
위 코드와 같이 gear는 이중 배열로 i가 1일 때 gear[i]는 1번 톱니에 해당한다.
gearPoint는 12시 방향을 가리키는 index에 해당하고 마찬가지로 i가 1일 때
grearPoint[i]는 1번 톱니의 12시 방향을 가리키는 index이다.
func rotation(num: Int, direction: Int, p: Int) {
if !(1...4).contains(num) { return }
var left = false
var right = false
if (1...4).contains(num - 1)
&& gear[num][(gearPoint[num] + 6) % 8] != gear[num - 1][(gearPoint[num - 1] + 2) % 8]
&& p != num - 1 {
left = true
}
if (1...4).contains(num + 1)
&& gear[num + 1][(gearPoint[num + 1] + 6) % 8] != gear[num][(gearPoint[num] + 2) % 8]
&& p != num + 1 {
right = true
}
if direction == 1 {
if gearPoint[num] == 0 {
gearPoint[num] = 7
} else {
gearPoint[num] -= 1
}
} else if direction == -1 {
gearPoint[num] = (gearPoint[num] + 1) % 8
}
if left {
rotation(num: num - 1, direction: direction * -1, p: num)
}
if right {
rotation(num: num + 1, direction: direction * -1, p: num)
}
}
이번엔 회전에 대한 코드를 보면,
rotation라는 메서드를 통해 톱니를 회전시켰다.
매개변수로는 회전시킬 톱니의 번호(num),
회전 방향(direction),
영향을 받은 톱니 번호(p)로 구성되어 있다.
먼저 들어온 톱니가 1번부터 4번에 포함되어 있는지 확인 후 해당 톱니가 돌아갔을 때 왼쪽 오른쪽 톱니가 영향을 받는지 플러그를 통해 체크한다.
영향을 받는지 체크하는 방법은 먼저 왼쪽 또는 오른쪽 톱니바퀴가 똑같이 1번부터 4번에 포함되어 있는지 확인하고, 방향에 맞게 2시 방향 톱니와 10시 방향 톱니를 확인한다.
마지막으로 영향받은 톱니인지 확인한다.
왼쪽 톱니바퀴의 영향을 받아 회전했을 때, 왼쪽 톱니바퀴를 또 회전시키지 않기 위함이다.
영향을 줄 톱니바퀴의 체크가 끝났으면 회전 방향에 맞게 gearPoint를 수정한다.
마지막으로 재귀를 통해 다음 톱니를 회전시키면 문제를 해결할 수 있다.
전체코드
import Foundation
var gear: [[Character]] = Array(repeating: [], count: 5)
var gearPoint = [0,0,0,0,0]
for i in 1...4 {
let input = Array(readLine()!)
gear[i] = input
}
func rotation(num: Int, direction: Int, p: Int) {
if !(1...4).contains(num) { return }
var left = false
var right = false
if (1...4).contains(num - 1)
&& gear[num][(gearPoint[num] + 6) % 8] != gear[num - 1][(gearPoint[num - 1] + 2) % 8]
&& p != num - 1 {
left = true
}
if (1...4).contains(num + 1)
&& gear[num + 1][(gearPoint[num + 1] + 6) % 8] != gear[num][(gearPoint[num] + 2) % 8]
&& p != num + 1 {
right = true
}
if direction == 1 {
if gearPoint[num] == 0 {
gearPoint[num] = 7
} else {
gearPoint[num] -= 1
}
} else if direction == -1 {
gearPoint[num] = (gearPoint[num] + 1) % 8
}
if left {
rotation(num: num - 1, direction: direction * -1, p: num)
}
if right {
rotation(num: num + 1, direction: direction * -1, p: num)
}
}
var result = 0
let n = Int(readLine()!)!
for _ in 0..<n {
let input = readLine()!.split(separator: " ").map { Int($0)! }
let num = input[0]
let direction = input[1]
rotation(num: num, direction: direction, p: 0)
}
for i in 1...4 {
if gear[i][gearPoint[i]] == "1" {
result += Int(pow(2, Double(i - 1)))
}
}
print(result)
'코테' 카테고리의 다른 글
[구현] 백준 실버3 2503번: 숫자 야구(Swift) (0) | 2023.07.08 |
---|---|
[구현 + BFS] 백준 골드3 16236번: 아기 상어(Swift) (0) | 2023.06.22 |
[백트래킹 + 구현] 백준 실버1 14888번: 연산자 끼워넣기(Swift) (0) | 2023.06.09 |
[백트래킹 + 구현] 백준 실버2 14889번 스타트와 링크(Swift) (0) | 2023.06.09 |
[다이나믹 프로그래밍 + 그리디] 백준 실버5 14916번: 거스름돈(Swift) (0) | 2023.05.29 |