본문 바로가기

너와!나의!알고!리즘!/SWEA

[SWEA #4013, Python] 특이한자석

[문제]

문제가 블라블라 엄청 길지만, 결국 붙어있는 녀석들이랑 극 확인하고 => 다르면 회전시키고 최종적으로 빨간 화살표 지점의 극을 구해서 점수 계산해라라는 문제!

엔지니어링 선표는 일을 하던 도중 창고에서 특이한 자석이 놓여있는 판을 발견했다.

이 판에는 4개의 자석이 놓여져 있었고, 각 자석은 8개의 ’(튀어나온 곳)를 가지고 있다.

자석의 각 날 마다 N 극 또는 S 극의 자성을 가지고 있다.

이 특이한 자석은 [Fig. 1] 과 같이 1 번부터 4 번까지 판에 일렬로 배치되어 있고,

빨간색 화살표 위치에 날 하나가 오도록 배치되어 있다.

 

                       

심심한 선표는 이 특이한 자석을 가지고 놀아보니 신기한 규칙을 발견했다.

임의의 자석을 1 칸씩 K 번 회전시키려고 해보니,

하나의 자석이 1 칸 회전될 때, 붙어 있는 자석은 서로 붙어 있는 날의 자성과 다를 경우에만 인력에 의해 반대 방향으로 1 칸 회전된다.

이를 신기하게 생각한 선표는 무작위로 자석을 돌렸을 때, 모든 회전이 끝난 후, 아래와 같은 방법으로 점수를 계산을 하고자 한다.

- 1 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0 , S 극이면 1 점을 획득한다.

- 2 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0 , S 극이면 2 점을 획득한다.

- 3 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0 , S 극이면 4 점을 획득한다.

- 4 번 자석에서 빨간색 화살표 위치에 있는 날의 자성이 N 극이면 0 , S 극이면 8 점을 획득한다.

 

4 개 자석의 자성 정보와 자석을 1 칸씩 K 번 회전시키려고 할 때,

K 번 자석을 회전시킨 후 획득하는 점수의 총 합을 출력하는 프로그램을 작성하라.

 

[예시]

[Fig. 1] 과 같이 자석의 자성 정보가 주어지고, 아래의 순서와 같이 자석을 1 칸씩 2 번 회전시키는 경우를 생각해보자.

① 1 번 자석을 시계방향으로 회전

② 3 번 자석을 반시계 방향으로 회전

 

[Fig. 2-1] 에서 1 번 자석을 시계방향으로 1 칸 회전시키면, 2 번 자석은 1 번 자석과 서로 붙어 있는 날의 자성이 달라 반시계 방향으로 1 칸 회전된다.

이 때, 3 번 자석은 2 번 자석과 서로 붙어 있는 날의 자성이 N 극으로 같아서 회전되지 않는다.

3 번 자석이 회전되지 않기 때문에 4 번 자석도 회전되지 않는다.



                      


[Fig. 2-1] 의 회전 결과는 [Fig. 2-2] 이다.


                      


[Fig. 2-2] 에서 3 번 자석을 반시계 방향으로 1 칸 회전시키면, [Fig. 3-1] 과 같이 자석들이 회전하게 된다.


                      


[Fig. 3-1] 의 회전 결과는 [Fig. 3-2] 이다.


                      


 

모든 자석의 회전이 끝난 후 획득하는 점수는 0 + 2 + 0 + 8 = 10 이 된다.

따라서, 이 예제의 정답은 10 이다.

 

[풀이]

BFS & 재귀를 이용했다. 우선 회전하는 녀석의 왼쪽-오른쪽과의 극을 비교하고, 걔네랑 맞닿은 부분이 극이 다르면 바로 그녀석을 재귀로 넣어주어서 그녀석의 좌우 다시 탐색.. 그리고 바퀴가 끝이라면 주어지는 회전 방향을 가지고 회전한다.

이때, 처음에 원형큐를 쓸려고 했는데 아 머리가 너무 아파서 (각 자석별 front,rear등등 다 다르게 설정해줘야함) 시간이 오래걸리더라도 pop을 사용했다. 토마토에서 익힌 deque내장 쓰면 개꿀,,

아 그리고 20분넘게 답이 안나와서 고민했는데 ㅋㅋㅋㅋ아 바보다,,, 시계방향을 -1로 둬서 못풀었던거임 넘나리 허무..

from collections import deque
def round(n,d):
    #회전하는애 양 옆 탐색
    left_c = n-1 #왼쪽 자석
    right_c = n + 1 #오른쪽 자석
    if 0<=left_c:
        if arr[n][6] != arr[left_c][2] and visit[left_c][2]== 0:
            visit[left_c][2] =1
            visit[n][6] = 1
            #왼쪽 자석 반대방향으로 회전하기 전에 옆에 녀석 탐색
            round(left_c,-d)
    if right_c<4:
        if arr[n][2] != arr[right_c][6] and visit[right_c][6] == 0:
            visit[right_c][6] = 1
            visit[n][2] = 1
            round(right_c,-d)
    if d == 1: #반시계방향
        x = arr[n].pop()
        arr[n].insert(0,x)
        return
    else:
        x = arr[n].popleft()
        arr[n].append(x)
        return

def score():
    global total
    for i in range(4):
        if arr[i][0] == 0:
            total += 0
        elif arr[i][0] == 1:
            total += (2**i)


T = int(input())
for tc in range(1,T+1):
    K = int(input())
    arr = []
    total = 0
    for _ in range(4):
        tmp = deque(list(map(int,input().split())))
        arr.append(tmp)
    for _ in range(K):
        n, d = map(int,input().split())
        visit=[[0]*7 for _ in range(4)]
        round(n-1,d)
    score()
    print('#{} {}'.format(tc,total))

'너와!나의!알고!리즘! > SWEA' 카테고리의 다른 글

[SWEA #1244, Python] 최대상금  (0) 2021.04.14
[SWEA #1232,Python] 사칙연산  (0) 2021.04.05
[SWEA #1231, Python ] 중위순회  (0) 2021.04.05