728x90
SMALL
문제 요약
- 4개의 톱니바퀴를 명령에 맞춰 시계 또는 반시계 방향으로 회전시키는 문제
- 회전할 때 맞닿은 톱니(3시와 9시 방향)의 극(S, N)이 다르면 맞닿은 톱니바퀴는 반대 방향으로 회전
- 모든 회전 후, 각 톱니바퀴의 12시 방향의 극 상태를 기준으로 점수를 합산해 결과 출력
풀이 코드
'''
2
3 -1 -> -1은 반시계, 3번 톱니를 반시계 방향으로 돌려라
1 1
'''
'''
서로 맞물려있는 극과 배열 회전이 중요한 문제
다 돌리고 나서 점수 합산을 12시 기준으로 한다는 것? N극이면 0, S면 1점(1번 톱니 기준)
'''
import sys; input=sys.stdin.readline
from collections import deque
def checking_saw(num, dir):
'''
필요한 값은 1: saw[0][2], 2: saw[1][-2], 3: saw[2][2], 4: saw[3][-2]
맞물린 극에 따라서 톱니들의 돌아갈 방향을 정해주는 함수
하나가 정해지게 되면 옆 톱니들에게 전파를 해줘야 함
'''
global saw
# 각 톱니마다 1인지, -1인지 방향 담아주기
dirs = [0] * 4
dirs[num] = dir
# 왼쪽으로 전파하기
for i in range(num-1, -1, -1):
if saw[i][2] != saw[i+1][-2]:
dirs[i] = -dirs[i+1]
else:
break
# 오른쪽으로 전파하기
for i in range(num+1, 4):
if saw[i][-2] != saw[i-1][2]:
dirs[i] = -dirs[i-1]
else:
break
return dirs
def turning_saw(dirs):
global saw
for i in range(4):
if dirs[i] != 0:
saw[i].rotate(dirs[i])
saw = [deque(map(int, input().rstrip())) for _ in range(4)]
K = int(input())
for _ in range(K):
num, dir = map(int, input().split())
dirs = checking_saw(num-1, dir)
turning_saw(dirs)
total_score = 0
for i in range(4):
if saw[i][0] == 1:
total_score += 2 ** i
print(total_score)

배운 점
- 어떤 톱니를 어느 방향으로 돌릴지 결정하는 함수(checking_saw)와, 방향대로 실제 회전을 수행하는 함수(turning_saw)를 분리해서 로직이 꼬이는 것을 방지할 수 있었음
- 시뮬레이션 문제에서는 상태를 변수나 배열에 저장하는 구조가 많이 사용되는 듯함. dirs라는 1차원 배열에 4개 톱니바퀴의 회전 방향을 미리 저장해둘 수 있었고, 이어지는 회전 함수에게 바로 던져줄 수 있어 편했음
- 선택된 톱니바퀴(num)를 기준으로 왼쪽과 오른쪽으로 퍼져나가는 반복문들을 설정해둬서, 맞물리는 조건(saw[i][2] - 3시 방향이나 saw[i+1][-2] - 9시 방향)을 따로 체크해줄 수 있었음
- collections.deque에서 제공해주는 rotate() 메서드로 배열 회전을 아주 간결하고 가독성 있게 구현할 수 있었음
728x90
LIST
'알고리즘 문제 풀이 > 랜덤 마라톤 (solved.ac)' 카테고리의 다른 글
| 🥇 12757번: 전설의 JBNU (0) | 2025.09.30 |
|---|---|
| 🥇 2230번: 수 고르기 (0) | 2025.02.26 |
| 🥈 24417번: 알고리즘 수업 - 피보나치 수 2 (2) | 2025.01.31 |
| 🥈 2303번: 숫자 게임 (1) | 2024.11.25 |
| 🥈 3060번: 욕심쟁이 돼지 (5) | 2024.10.07 |