4013. 특이한 자석
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
- 내 풀이
- 점수기준값인 point값을 수정해가면서 진행
- 시계방향일때 point는 왼쪽으로 작아지고, 반시계방향일때는 오른쪽으로 커지도록 함 (처음에 헷갈려서 반대로함 주의)
- 옆에 자석이랑 비교할때 현재 point값을 위에서 바꿔주기 때문에 기존의 point값을 저장해두고 그 위치기준으로 비교해야함
- 현재 자석을 돌리면서 그 다음자석이 돌려진 후에, 다시 현재자석을 또 돌리지 못하도록 visited처리 해줘야함
#SW 4013
#4개 자석 k번 돌린 전부 돌린 후 점수
# 점수: n극 0점, s극 2의 자석번호 제곱수만큼1,2,4,8(0~3 제곱)
#시계방향 1 반시계방향 -1
#n극 0 s극 1
def point_check(pnt): #접하는 지점
if pnt-2<0:
pnt+=8
return pnt-2
def rotate(m,dir):
visited[m]=True
p=point[m] #기존 포인트값
if dir==1: #시계방향일때 왼쪽으로(작아짐)
if point[m]==0:
point[m]=7
else:
point[m]-=1
#접하는 면이 자석이 반대일때만 실행
#위에서 point바뀌기 전값으로 생각해야함
if m+1<=3 and magnet[m][(p+2)%8] != magnet[m+1][point_check(point[m+1])]: #우측 자석
if visited[m+1]==False:
rotate(m+1, -1)
if m-1>=0 and magnet[m][point_check(p)]!=magnet[m-1][(point[m-1]+2)%8]:
if visited[m-1]==False:#좌측 자석
rotate(m-1,-1)
else: #반시계방향일때 오른쪽으로(커짐)
point[m]=(point[m]+1)%8
#자석 반대면 실행
if m+1<=3 and magnet[m][(p+2)%8]!=magnet[m+1][point_check(point[m+1])]:
if visited[m+1]==False:
rotate(m+1, 1)
if m-1>=0 and magnet[m][point_check(p)]!=magnet[m-1][(point[m-1]+2)%8]:
if visited[m-1]==False:
rotate(m-1,1)
T=int(input())
for tc in range(1,T+1):
k=int(input())
magnet=[]
for i in range(4):
#magnet[0] 위치가 점수계산할 위치
magnet.append(list(map(int,input().split())))
rotation=[]
for j in range(k):
#자석번호, 회전방향 [a,b]
a,b=map(int,input().split())
a-=1 #0~3번 자석으로 인덱스=이름 맞추기
rotation.append([a,b])
point=[0]*4 #점수위치
#회전
for rt in rotation:
visited=[False]*4
m,dir=rt #자석번호, 방향
rotate(m,dir)
result=0
for idx, p in enumerate(point):
if magnet[idx][p]==0: continue #n극 0점
else:
result+=2**idx
print(f'#{tc} {result}')
백준 14891이랑 같은문제
14891번: 톱니바퀴
총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴
www.acmicpc.net
- 다른 사람 풀이
- 시계, 반시계방향으로 회전 시키기위해 양 끝에서 값을 뺄 수있는 deque이용
- 딕셔너리를 이용해서 deque()을 value로 넣고 gears[key][value] 로 호출함
- 회전을 deque. rotate() 함수 이용
- 왼쪽방향 탐색할때는 계속 왼쪽방향만, 오른쪽 방향탐색때는 계속오른쪽만 탐색하기때문에 visited 필요없음
- 기준 톱니바퀴가 있을 때, 왼쪽과 맞닿는 지점은 idx 2, 오른쪽은 6 !!! (내가 완전 복잡하게 처리한 부분)
- 시계, 반시계방향으로 회전 시키기위해 양 끝에서 값을 뺄 수있는 deque이용
deque.rotate()
import sys
from collections import deque
input=sys.stdin.readline
# 문제의 경우 1은 시계방향, -1은 반시계 방향이다.
# deque의 rotate = -1일 경우 반시계 방향, 1일 경우 시계 방향으로 움직인다.
def check_right(start, dirs):
# 더 이상 조사가 불가능한 경우
if start > 4 or gears[start-1][2] == gears[start][6]:
return
#계속 오른쪽 탐색
check_right(start + 1, -dirs)
#회전
gears[start].rotate(dirs)
def check_left(start, dirs):
if start < 1 or gears[start][2] == gears[start+1][6]:
return
check_left(start - 1, -dirs)
gears[start].rotate(dirs)
gears = {}
# 기준 톱니바퀴가 있을 때, 왼쪽과 맞닿는 지점은 idx 2, 오른쪽은 6이다.
for i in range(1, 5):
gears[i] = deque(map(int, list(input().rstrip())))
n = int(input())
for _ in range(n):
num, dirs = map(int, input().split())
# 기준 톱니바퀴가 주어졌을 때, 오른쪽 / 왼쪽이 회전 가능한지를 각각 확인하고 회전시킨다.
check_right(num+1, -dirs)
check_left(num-1, -dirs)
# 기준 톱니바퀴를 회전시킨다.
gears[num].rotate(dirs)
result = 0
for i in range(4):
result += (2**i) * gears[i+1][0] #n극이라 0이면 곱해서 0 되므로
print(result)
이렇게 간결할 수가.........끄악
'코딩테스트 > BOJ' 카테고리의 다른 글
| [백준] [DFS] [트리] 1967. 트리의 지름 (0) | 2023.04.12 |
|---|---|
| [백준] [백트래킹] 18430. 무기 공학 (0) | 2023.04.10 |
| [백준] [백트래킹] 16987. 계란으로 계란치기 (0) | 2023.04.09 |
| [백준][백트래킹] N과 M 2~12 번 모음 (0) | 2023.04.08 |
| [SWEA] 2112. 보호필름 (0) | 2023.04.07 |