이숭간 공부기록

백준 14891번 파이썬 _ 톱니바퀴 (삼성 SW 역량 테스트 기출 문제 ) 본문

알고리즘/백준

백준 14891번 파이썬 _ 톱니바퀴 (삼성 SW 역량 테스트 기출 문제 )

이숭간 2021. 2. 9. 22:02
728x90

www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

첫째 줄에 1번 톱니바퀴의 상태, 둘째 줄에 2번 톱니바퀴의 상태, 셋째 줄에 3번 톱니바퀴의 상태, 넷째 줄에 4번 톱니바퀴의 상태가 주어진다. 상태는 8개의 정수로 이루어져 있고, 12시방향부터

www.acmicpc.net

문제유형 : 구현, 시뮬레이션

문제핵심 : 생각한 아이디어를 구현으로 잘 옮기는것..

 

우선 푸는데 좀 오래걸렸다.

이런 구현이나 시뮬레이션 문제는 이렇다할 팁..? 이 없는거같아서 어떻게 정리해야할지 모르겠다.

 

미래의 내가 다시 풀어도 또 오래걸릴거같은 느낌이다 

 

뭔가 생각할수록 점점 복잡해져서 하던 생각(?)을 끝까지 이어가지않고 자꾸 다른 더 간단한 방법을 찾으려고해서 점점더 생각이 정리되지않고 산으로 가는 느낌을 받았다.

일단 한번 생각한 방향대로 쭉 밀고 나가는것도 필요한것같다. ( 너무 말도안되는 방법이 아니라면?)

반복문과 조건문 중첩이 아주 더러운데 어차피 4개뿐이라서 시간초과는 나지 않았다.

 

내가푼방법:

 

1. 시계방향 / 반시계방향으로 움직이게하는 함수정의

 

2. 한번의 rotate마다 turn배열을 정의한다.

 

turn배열은 현재 돌리려는 톱니바퀴에 의해 돌아갈수있는 톱니바퀴를 True로 돌아갈수 없는 톱니바퀴는 False로 둔 배열이다.

 

문제예시로 예를들면 최초상태에서 3번톱니바퀴를 반시계방향으로 돌릴때, 이것에 의해 돌아갈수있는 톱니바퀴는 4번뿐이다. 이때 turn배열은 [F, F, T, T]가 된다.  그다음 1번톱니바퀴를 시계방향으로 돌릴때, 1번에의해 돌아갈수있는 톱니바퀴는 2,3번 톱니바퀴이다. 이때 turn배열은 [T,T,T,F]가 된다.

 

3. 회전을 수행하는데 이때 나올수있는 경우의수는 2가지로

  • 돌리려는 톱니바퀴가 홀수+시계, 짝수+반시계 이면, 홀수는 시계방향으로 짝수는 반시계방향으로 돌림 
  • 돌리려는 톱니바퀴가 짝수+반시계, 홀수+시계이면, 짝수는 반시계방향, 홀수는 시계방향으로 돌린다.

4. 최종적으로 turn배열을 확인하면서 False일때는 넘어가고 True인것만 돌려주면 되는데 돌리는것은 위에언급한대로 돌려주면 된다.

 

# 새로배운 스킬:

math.pow(a,b) : a의 b제곱승

input_list = [list(map(int, input())) for _ in range(4)]
k = int(input())

rotate = [list(map(int, input().split())) for _ in range(k)]

def clock(l):
    a = l[-1:]
    a.extend(l[:-1])
    return a

def opp_clock(l):
    a = l[1:]
    a.append(l[0])
    return a

turn = [False] * 4

for i in rotate: # i = 3 -,1
    curr = i[0]-1
    turn[curr] = True
    for j in range(curr, 4): #나를 기준으로 오른쪽확인
        if j<3 and (input_list[j][2] == input_list[j+1][6]):
            turn[j+1] = False
            break
        elif j<3:
            turn[j+1] = True
    for k in range(curr, -1, -1): #나를 기준으로 왼쪽 확인, 0까지 거꾸로 
        if k>0 and input_list[k][6] == input_list[k-1][2]:
            turn[k-1] = False
            break
        elif k>0:
            turn[k-1] = True
            
	# turn배열 완성
    if (curr%2==0 and i[1]==1) or (curr%2!=0 and i[1]==-1): #홀수는 반시계방향, 짝수는 시계방향
        for check in range(len(turn)):
            if turn[check] == False:
                continue
            elif check%2==0:
                input_list[check] = clock(input_list[check])
            else:
                input_list[check] = opp_clock(input_list[check])
    else: #홀수는 시계방향, 짝수는 반시계방향
        for check in range(len(turn)):
            if turn[check] == False:
                continue
            elif check%2==0:
                input_list[check] = opp_clock(input_list[check])
            else:
                input_list[check] = clock(input_list[check])
	
    # 다음회전을 위해 turn배열 초기화 
    turn = [False] * 4

count = 0
import math
for i in range(4):
    if input_list[i][0] == 1: #12시방향이 S극이면
        count += int(math.pow(2,i))

print(count)