https://www.acmicpc.net/problem/14891
14891번: 톱니바퀴
총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴
www.acmicpc.net
<복습 체크>
22/03/05 | |||||||||
O |
<내 코드 1>
- 회전을 할 때 deque의 rotate를 이용해서 회전했다.
- check_right 함수는 회전하는 톱니바퀴를 기준으로 오른쪽 바퀴들의 회전 여부를 파악하는 함수이다.
-> k번째 톱니바퀴의 인덱스 2번과 k+1번째 톱니바퀴의 인덱스 6번을 비교해야한다.
-> 만약 서로 다르다면 원래 회전 방향 d와 반대로 회전해야하기 때문에 d = -d로 변경해주었다
-> 서로 같은 경우에는 더 이상 회전을 하지 않으므로 리턴했다.
- check_left 함수는 회전하는 톱니바퀴를 기준으로 왼쪽 바퀴들의 회전 여부를 파악하는 함수이다.
-> k번째 톱니바퀴의 인덱스 6번과 k-1번째 톱니바퀴의 인덱스 2번을 비교해야한다.
- check 리스트는 회전여부를 파악하는 배열이다. 우선 명령의 톱니바퀴 번호 인덱스에 방향을 저장한다.
- 그 후 톱니바퀴 번호에 따라 회전 여부를 파악해서 check 리스트를 업데이트한다.
[헷갈린 부분]
- 나는 톱니바퀴가 순차적으로 회전하는 문제라고 생각해서 시간을 많이 썼다.
-> 1번 바퀴가 회전하는 경우
-> 1번 바퀴 회전 -> 2번 바퀴랑 겹치는지 확인해서 회전 -> 3번 바퀴 겹치는지 확인해서 회전
위와 같은 방식으로 동작한다고 착각했다.
- 이 문제는 1번 바퀴가 회전한다고 가정하면, 회전 하기 전의 바퀴들의 맞물림 상태를 확인해서 회전 방향을 미리 결정하는 문제이다.
import sys
from collections import deque
input = sys.stdin.readline
def check_right(num, d):
for k in range(num-1, 3):
if gear[k][2] != gear[k + 1][6]:
d = -d
check[k + 1] = d
else:
return
def check_left(num, d):
for k in range(num - 1, 0, -1):
if gear[k][6] != gear[k - 1][2]:
d = -d
check[k - 1] = d
else:
return
gear = []
for _ in range(4):
gear.append(deque(map(int, input().strip())))
k = int(input())
order = []
for _ in range(k):
order.append(list(map(int, input().split())))
for i in range(k):
num, d = order[i][0], order[i][1]
check = [0]*4
check[num-1] = d
## 회전 여부 확인 ##
if num == 1:
check_right(num,d)
elif num == 2:
if gear[num - 1][6] != gear[0][2]:
check[0] = -d
check_right(num, d)
elif num == 3:
if gear[num - 1][2] != gear[3][6]:
check[3] = -d
check_left(num, d)
else:
check_left(num, d)
## 회전 ##
for i in range(4):
if check[i]:
gear[i].rotate(check[i])
## 출력 ##
ans = 0
for i in range(4):
if gear[i][0] == 1:
ans += 2**i
print(ans)
<내 코드 2>
- 극강의 노가다로 코드를 짰다,, 매번 1시간 미만으로 고민하다가 다른 풀이 참고하면서 익혔는데 오늘은 오기가 생겨서
끝까지 해봤다,,, 맨처음에는 문제를 잘못 이해했고,, 그 다음엔 중간중간 잘못 생각한 부분이 있었다.
- 3시간 넘게 붙잡고 있었던것같다,, 우선 내 노가다 코드를 올리고 다른 사람 코드 보면서 공부를 더 해야겠다
- 시계 방향, 반시계 방향 회전 함수를 스택을 이용해 직접 구현했다.
# 톱니바퀴
t = []
for _ in range(4):
t.append(list(map(int, input())))
k = int(input())
orders = []
# 톱니바퀴 번호와 회전방향 입력받음
for _ in range(k):
num, ro = map(int, input().split())
orders.append([num, ro])
#회전 함수
def rotation(num, directions):
if directions == 1: # 시계 방향
t[num].reverse() # 뒤집어줌
temp = t[num].pop(0) # 맨앞에꺼 뺌
t[num].append(temp) # 맨 뒤에 붙임
t[num].reverse() # 다시 뒤집어줌
elif directions == -1: # 반시계 방향
temp = t[num].pop(0) # 맨앞에꺼 뺌
t[num].append(temp) # 맨 뒤에 붙임
for order in orders:
num, d = order[0] - 1, order[1]
# 옆 톱니들 확인
check = [0] * 4
check[num] = d
flag = False #연속적으로 회적이 일어나는지 체크해주는 변수
if num == 0:
if t[0][2] != t[1][6]: # 극이 다르다면
check[1] = -d
flag = True
if t[1][2] != t[2][6] and flag == True:
check[2] = d
else:
flag = False
if t[2][2] != t[3][6] and flag == True:
check[3] = -d
elif num == 1:
if t[1][6] != t[0][2]:
check[0] = -d
if t[1][2] != t[2][6]:
check[2] = -d
flag = True
if t[2][2] != t[3][6] and flag == True:
check[3] = d
elif num == 2:
if t[2][2] != t[3][6]:
check[3] = -d
if t[2][6] != t[1][2]:
check[1] = -d
flag = True
else:
flag = False
if t[1][6] != t[0][2] and flag == True:
check[0] = d
elif num == 3:
if t[3][6] != t[2][2]: # 극이 다르다면
check[2] = -d
flag = True
if t[2][6] != t[1][2] and flag == True:
check[1] = d
else:
flag = False
if t[1][6] != t[0][2] and flag == True:
check[0] = -d
#회전 동작
for i in range(4):
if check[i]:
rotation(i, check[i])
result = 0
cnt = 1
for i in range(4):
if t[i][0] == 1: # s극이면
result+=cnt
cnt *= 2
print(result)
'알고리즘 > 삼성' 카테고리의 다른 글
[백준-실버2] 14889번 스타트와 링크 (완전탐색, 파이썬) (0) | 2022.02.07 |
---|---|
[백준 -실버1] 14888번 연산자 끼워넣기(완전탐색, 파이썬) (0) | 2022.02.07 |
[백준 -골드5] 14502번 연구소(BFS, 완전탐색, 파이썬) (0) | 2022.02.04 |
[백준 -골드5] 15686번 치킨 배달(완전탐색, 파이썬) (0) | 2022.02.04 |
[백준 -골드5] 14503번 로봇 청소기(구현, 파이썬) (0) | 2022.02.04 |