[문제]
문제가 블라블라 엄청 길지만, 결국 붙어있는 녀석들이랑 극 확인하고 => 다르면 회전시키고 최종적으로 빨간 화살표 지점의 극을 구해서 점수 계산해라라는 문제!
엔지니어링 선표는 일을 하던 도중 창고에서 특이한 자석이 놓여있는 판을 발견했다.
이 판에는 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 |