Algorithm Problem/Python

[python] 백준 - 14891. 톱니바퀴 (삼성 SW 역량 테스트 기출 문제)

deo2kim 2020. 5. 12. 22:50
반응형

출처 : BACKJOON ONLINE JUDGE

문제 :  https://www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴

www.acmicpc.net

 

문제 해결 순서

1. 각 톱니바퀴의 왼쪽(6번 인덱스) 오른쪽(2번 인덱스)를 이용하여 회전 가능 여부를 검사한다.

2. 처음 정해진 톱니바퀴와 인접한 톱니바퀴가 회전할 수 있는지를 검사한다.

3. 인접한 톱니바퀴가 회전할 수 있다면 그 톱니바퀴에 인접한 톱니바퀴를 다시 검사한다.

4. 처음 정해진 톱니바퀴의 회전방향에 따라 각 톱니바퀴의 회전방향이 결정된다.

5. 인접한 톱니바퀴가 회전하지 않더라도 처음 정해진 톱니바퀴는 무조건 회전해야 한다.

 

 -> 5번을 조건을 디버깅 하면서 알게 됐다. / 인접한 톱니바퀴가 회전하지 않으면 처음 정해진 톱니바퀴도 회전을 하지않아서 이걸 찾는데 꽤 오래 걸렸다.

 

 + rotate함수를 사용하려고 했으나 까먹어서 사용하지 못했다. ( rotate는 deque로 사용할 수 있다 )

그냥 슬라이싱을 이용해 앞뒤를 바꿔주는 방법을 사용.

 

 ※ 특별한 알고리즘 없이 제시된 상황을 구현하는 문제이다.

 

소스코드

gear = [list(input()) for _ in range(4)]  # 톱니
k = int(input())  # 회전수

for i in range(k):
    n, d = map(int, input().split())
    n -= 1  # 톱니바퀴 인덱스는 0부터

    # 0번 12시방향, 2번 오른쪽, 6번 왼쪽
    pole = []  # 각 톱니의 왼쪽과 오른쪽을 배열에 저장
    rotationCheck = [0]*4  # 회전을 할지 말지 저장
    ds = [1, -1, 1, -1]  # 각 톱니의 회전 방향

    while True:  # 처음 회전할 톱니의 방향을 결정하고 그 방향에 따라 나머지를 반대방향으로 설정해준다.
        if ds[n] == d:
            break
        else:
            ds = ds[3:] + ds[:3]

    for j in range(4):  # 각 톱니의 왼쪽과 오른쪽을 배열에 저장
        pole.append(gear[j][6])
        pole.append(gear[j][2])

    br = n * 2 - 1  # 현재 기준 왼쪽 톱니의 오른쪽
    cl = n * 2      # 현재 기준 현재 톱니의 왼쪽

    cr = n * 2 + 1  # 현재 기준 현재 톱니의 오른쪽
    nl = n * 2 + 2  # 현재 기준 오른쪽 톱니의 왼쪽

    # 왼쪽 톱니 확인
    while True:
        if br < 1:
            break

        if pole[br] != pole[cl]:
            rotationCheck[br // 2] = 1
            rotationCheck[br // 2 + 1] = 1
            br -= 2
            cl -= 2
        else:
            break

    # 오른쪽 톱니 확인
    while True:
        if nl > 6:
            break

        if pole[cr] != pole[nl]:
            rotationCheck[cr // 2] = 1
            rotationCheck[cr // 2 + 1] = 1
            cr += 2
            nl += 2
        else:
            break

    if sum(rotationCheck) == 0:  # 맞물리는 톱니가 없을 때 혼자 회전
        if d == -1:
            gear[n] = gear[n][1:] + gear[n][:1]
        elif d == 1:
            gear[n] = gear[n][7:] + gear[n][:7]

    else:
        for j in range(4):
            if rotationCheck[j] == 1:
                if ds[j] == -1:  # 반시계
                    gear[j] = gear[j][1:] + gear[j][:1]

                elif ds[j] == 1:  # 시계
                    gear[j] = gear[j][7:] + gear[j][:7]

# 톱니의 점수 계산
result = 0
for i in range(4):
    if gear[i][0] == '1':
        result += 2**i

print(result)

 

반응형