Algorithem/백준 PS with code
백준 #14891 - 톱니바퀴 : 구현
jamong5
2023. 5. 19. 12:24
(python3)
구현 아이디어
이 문제의 경우 4개의 톱니를 동시에 회전시키는 것 처럼 구현해줄 필요가 있었습니다. 톱니 상황을 하나씩 업데이트 하다 보면 의도한 방향으로 상호작용이 일어나지 않을 수 있기 때문에 이를 고려해줄 필요가 있습니다.
크게 2단계로 구현을 분리했습니다.
1단계 : N번 톱니를 r 방향으로 회전시킬 때, 현재 상황에서 회전될 모든 톱니들과 각 톱니의 회전 방향을 구한다.
이 단계에서는 현재 상황에서 톱니들의 사이에 일어날 상호작용만 체크하고 톱니 상황을 업데이트하지는 않습니다.
2단계 : 1단계에서 구한 정보를 토대로 톱니 방향을 회전시켜 톱니 상황을 업데이트한다.
구현 디테일
톱니의 상태를 배열로 나타내는데, 회전할때마다 배열의 모든 값을 밀거나 당기기는 방향으로 업데이트를 해줄 수 도 있지만, 어떤 톱니가 12시 방향을 가리키고 있는지, 인덱스를 짚어주는 int 값을 하나 따로 두는 방식으로도 관리해줄 수 있습니다.
저는 톱니가 서로 맞닿는 (상호작용이 일어나는) 6개의 포인트들의 인덱스를 gi 라는 배열로 따로 저장하여 관리했습니다. (12시 방향을 가리키는 인덱스만 관리하는게 편할 것 같긴 합니다.)
굉장히 하드코딩을 했기 때문에... 톱니 수가 많아지면 1단계 알고리즘을 많이 고쳐야할 듯 합니다.
# https://www.acmicpc.net/problem/14891
def solution(input) :
"""
톱니바퀴 번호 = 1, 2, 3, 4
톱니바퀴 초기 상태 G = [_,1,2,3,4]
톱니바퀴의 붙어있는 지점 (index) 를 표현한 dict : gi = [12, 21, 23, 32, 34, 43] 이 인덱스를 수정하면서 톱니의 회전을 표현
"""
# 기어 정보 받아오기 (12시부터 시계방향, N극 = 0, S극 = 1)
G = [0,]
for _ in range(4) :
g = input().strip()
gi = []
for t in g :
gi.append(int(t))
G.append(gi)
# 회전수 정보 받아오기
K = int(input())
# 회전할 톱니 번호와 방향 받아오기
R = []
for _ in range(K) :
R.append(tuple(map(int, input().split())))
# 톱니의 회전 상태를 표현해줄 gi 배열 생성
gi = [2,6,2,6,2,6]
def rotate(Gn, d) :
"""
n번 기어를 d 방향으로 회전 (기어의 상호작용은 고려 X)
"""
d = -d
if Gn == 1 :
gi[0]+=d
elif Gn ==2 :
gi[1]+=d
gi[2]+=d
elif Gn==3 :
gi[3]+=d
gi[4]+=d
else :
gi[5]+=d
for i, g in enumerate(gi) :
if g == 8 :
gi[i] = 0
elif g == -1 :
gi[i] = 7
def check_rotate_gear(M,r) :
"""
M 번 기어를 r 방향으로 회전할 때 회전될 모든 기어와 방향을 list 로 묶어서 반환
"""
rg = [(M,r)]
diff_pole = [G[1][gi[0]] != G[2][gi[1]],
G[2][gi[2]] != G[3][gi[3]],
G[3][gi[4]] != G[4][gi[5]]]
if M==1 :
if diff_pole[0] :
rg.append((2,-r))
if diff_pole[1] :
rg.append((3,r))
if diff_pole[2] :
rg.append((4,-r))
elif M==2 :
if diff_pole[0] :
rg.append((1,-r))
if diff_pole[1] :
rg.append((3,-r))
if diff_pole[2] :
rg.append((4,r))
elif M==3 :
if diff_pole[1] :
rg.append((2,-r))
if diff_pole[0] :
rg.append((1,r))
if diff_pole[2] :
rg.append((4,-r))
elif M==4 :
if diff_pole[2] :
rg.append((3,-r))
if diff_pole[1] :
rg.append((2,r))
if diff_pole[0] :
rg.append((1,-r))
return rg
def rotate_all(M,r) :
"""
M번 기어를 r 방향으로 회전할 때 상호작용을 고려하여 4개 기어를 모두 회전
"""
rotate_list = check_rotate_gear(M,r)
for i in rotate_list :
rotate(*i)
for r in R :
rotate_all(*r)
# 기어들의 12시 방향 극 확인
gear_12 = [G[1][gi[0]-2], G[2][gi[2]-2], G[3][gi[4]-2], G[4][gi[5]-6]]
# 점수 계산
score = [1,2,4,8]
final_score = 0
for a,b in zip(gear_12,score) :
final_score += a*b
print(final_score)
solution(input)