728x90
풀이일 : 2503237
난이도 : 골드5
https://www.acmicpc.net/problem/14891
문제
문제 생략 사진입니다.
아이디어
1. 각 톱니바퀴 12시 방향을 포인터로 사용
# 회전
모든 접점을 확인 후 한번에 회전
반시계 방향이면 포인터 + 1, 시계 방향 회전이면 포인터 + 7
# 점수 계산
1, 2, 3, 4 번 톱니바퀴의 포인터가 1이면 각 2^0 ~ 2^3
전체 풀이 코드
import sys
def spin(x, y): # 회전 여부 판단, 기록
if x < 0 or y > 3: # 톱니바퀴 존재 확인
return
# 왼쪽 톱니바퀴의 3시 방향과 오른쪽 톱니바퀴의 9시 방향 극 비교
# 같은 극일 경우
if cogwheels[x][(pointers[x] + 2) % 8] == cogwheels[y][(pointers[y] + 6) % 8]:
return
# 다른 극을 경우, 이전에 움직이지 않은 톱니바퀴의 회전 방향 기록
else:
if check[y]:
check[x] = check[y] * - 1
spin(x - 1, x)
else:
check[y] = check[x] * - 1
spin(y, y + 1)
return
# 입력 받기
cogwheels = [sys.stdin.readline().strip() for _ in range(4)] # 톱니바퀴 극 정보
K = int(sys.stdin.readline())
pointers = [0, 0, 0, 0] # 각 톱니바퀴의 포인터
score = 0
for _ in range(K):
num, direction = map(int, sys.stdin.readline().split())
check = [0, 0, 0, 0] # 회전 여부 및 방향 기록
check[num - 1] = 1 if direction < 0 else -1
# 회전할 톱니바퀴 양쪽 톱니바퀴 회전여부 판단
spin(num - 2, num - 1)
spin(num - 1, num)
for i in range(4): # 회전시키기
pointers[i] += check[i] if check[i] >= 0 else 7
pointers[i] = pointers[i] % 8
# 최종 결과 포인터 1이면 점수 획득
for i in range(4):
if cogwheels[i][pointers[i]] == '1':
score += 2 ** i
print(score)
상세 풀이 코드
def spin(x, y): # 회전 여부 판단, 기록
if x < 0 or y > 3: # 톱니바퀴 존재 확인
return
# 왼쪽 톱니바퀴의 3시 방향과 오른쪽 톱니바퀴의 9시 방향 극 비교
# 같은 극일 경우
if cogwheels[x][(pointers[x] + 2) % 8] == cogwheels[y][(pointers[y] + 6) % 8]:
return
# 다른 극을 경우, 이전에 움직이지 않은 톱니바퀴의 회전 방향 기록
else:
if check[y]:
check[x] = check[y] * - 1
spin(x - 1, x)
else:
check[y] = check[x] * - 1
spin(y, y + 1)
return
- 항상 왼쪽 톱니바퀴는 x로, 오른쪽 톱니바퀴는 y로 담아 함수를 호출한다.
- 톱니바퀴는 총 4개로, 0 ~ 3 인덱스를 사용한다. x가 0보다 작거나, y가 3보다 크게 주어지는 경우에는 함수를 종료한다.
- x 톱니바퀴의 3시 방향 극은 포인터(12시 방향)을 기준으로 +2를 8로 나눈 나머지 인덱스, y 톱니바퀴의 9시 방향 극은 포인터를 기준으로 +6을 8로 나눈 인덱스로 구해 두 인덱스의 극을 비교한다.
- 비교 결과가 같다면, 다음 톱니바퀴는 회전하지 않으므로 함수를 종료한다.
- 비교 결과가 다르다면, 이전에 회전한 톱니바퀴의 회전 방향과 반대를 표시해준다.
# 입력 받기
cogwheels = [sys.stdin.readline().strip() for _ in range(4)] # 톱니바퀴 극 정보
K = int(sys.stdin.readline())
pointers = [0, 0, 0, 0] # 각 톱니바퀴의 포인터
score = 0
- cogwheels : 톱니바퀴들의 극 정보를 기록한다. 모든 톱니바퀴는 한 배열로 관리하여 인덱스로 접근한다.
- pointers : 각 톱니바퀴들의 12시 방향을 기록한다. 톱니바퀴 회전 시 반시계 방향은 + 1, 시계 방향은 + 6해서 12시 방향을 추적한다.
for _ in range(K):
num, direction = map(int, sys.stdin.readline().split())
check = [0, 0, 0, 0] # 회전 여부 및 방향 기록
check[num - 1] = 1 if direction < 0 else -1
# 회전할 톱니바퀴 양쪽 톱니바퀴 회전여부 판단
spin(num - 2, num - 1)
spin(num - 1, num)
for i in range(4): # 회전시키기
pointers[i] += check[i] if check[i] >= 0 else 7
pointers[i] = pointers[i] % 8
- 회전할 톱니바퀴와 방향을 입력 받아 저장한다.
- check : 회전 여부 및 방향을 기록한다. 회전 편의를 위해 반시계 방향은 1, 시계 방향은 -1로 기록한다.
- 최초 회전한 톱니바퀴의 양쪽 톱니바퀴의 회전 여부를 확인하는 함수를 호출한다.
- 반복문을 수행하며, check 내용을 pointers에 반영해 톱니바퀴를 회전한다.
# 최종 결과 포인터 1이면 점수 획득
for i in range(4):
if cogwheels[i][pointers[i]] == '1':
score += 2 ** i
print(score)
- 모든 회전이 끝난 후, 각 톱니바퀴의 12시 방향 극을 확인하여, S극이라면 2의 톱니바퀴 인덱스 승만큼 점수를 더한다.
느낀점
- 문자열을 입력받을 때, 개행문자를 어떻게 없애는 지 기억나지 않아서 조금 헤맸다.
- 어렵지 않은 구현문제인데, 인덱스 설정이랑 회전 기록 등등 생각보다 오래 시간쓰고 풀어내서 알고리즘 열심히 해야겠다고 다시 다짐해본다.
'알고리즘 > 🥇 골드' 카테고리의 다른 글
백준 14567 선수과목 (Prerequisite) 파이썬 풀이 (1) | 2024.05.01 |
---|---|
백준 7579 앱 파이썬 풀이 (0) | 2024.04.25 |
백준 15486 퇴사 2 파이썬 풀이 (0) | 2024.04.24 |
백준 2470 두 용액 파이썬 풀이 (1) | 2024.04.22 |
백준 1976 여행 가자 파이썬 풀이 (0) | 2024.04.17 |