BAEKJOON Online Judge(BOJ) 문제입니다.
문제
https://www.acmicpc.net/problem/17837
내가 작성한 코드
from collections import deque, defaultdict
dir = [(0, 1), (0, -1), (-1, 0), (1, 0)]
def read_data():
N, K = map(int, input().rstrip().split())
board = []
chess = defaultdict(list)
pos = defaultdict(tuple)
for _ in range(N):
board.append(list(map(int, input().rstrip().split())))
for i in range(K):
r, c, d = map(int, input().rstrip().split())
chess[(r-1, c-1)].append(i)
pos[i] = (r-1, c-1, d-1)
return N, K, board, chess, pos
def in_range(r, c, N):
return 0 <= r < N and 0 <= c < N
def move_all(N, K, board, chess, pos):
def get_color(r, c):
# 색깔 찾기
if not in_range(r, c, N):
return 2
else:
return board[r][c]
def where(r, c, d):
nw_r, nw_c = r+dir[d][0], c+dir[d][1]
color = get_color(nw_r, nw_c)
# 도착지 확인
if color < 2:
return nw_r, nw_c, d, color
# 반대 방향 확인
d = d+1 if d%2==0 else d-1
nw_r, nw_c = r + dir[d][0], c + dir[d][1]
color = get_color(nw_r, nw_c)
if color == 2:
return None, None, d, None,
return nw_r, nw_c, d, color
def who(r, c, i, d, color):
# 위치 찾기
idx = chess[(r, c)].index(i)
# 옮길 체스 찾기
me = chess[(r, c)][idx:]
# 옮기기 전 체스 업데이트
chess[(r, c)] = chess[(r, c)][:idx]
if color == 1:
return me[::-1]
return me
for i in range(K):
r, c, d = pos[i]
nw_r, nw_c, d, color = where(r, c, d)
if nw_r is None:
pos[i] = (r, c, d)
continue
me = who(r, c, i, d, color)
# pos 업데이트
for j in me:
_r, _c, _d = pos[j]
if j == i:
pos[j] = (nw_r, nw_c, d)
else:
pos[j] = (nw_r, nw_c, _d)
# chess 업데이트
chess[(nw_r, nw_c)] += me
# 종료 확인
if len(chess[(nw_r, nw_c)]) >= 4:
return False
return True
def get_answer(N, K, board, chess, pos):
round = 1
while move_all(N, K, board, chess, pos) and round <= 1000:
round += 1
return round if round <= 1000 else -1
def debug(board, chess, pos):
print(f"++++++++++++++++++++++++")
print(f"chess:")
for k, v in chess.items():
print(f"{k} : {v}")
print()
print(f"pos:")
for k, v in pos.items():
print(f"{k} : {v}")
print()
N, K, board, chess, pos = read_data()
print(get_answer(N, K, board, chess, pos))
- [주의] 움직이지 못하는 말
- 진행방향, 반대방향이 모두 파란색 or 격자 밖인 경우
- 방향은 바꿔줘야함
- 다른 말이 데리고 나갈 경우, 움직일 수 있으면, 바뀌던 방향으로 진행해야함
- 진행방향, 반대방향이 모두 파란색 or 격자 밖인 경우
- chess : defaultdict(list)
- key=(r, c) / value = [(i, d)]
- r, c에 놓인 말 리스트
- i는 말의 번호
- d는 말의 방향
- pos : defaultdict(tuple)
- key = i / value = (r, c, d)
- 말 i가 있는 위치 (r, c)와 방향 d
- 말 옮기기
- 번호 순서대로 진행
- 1. 어디로(where) 옮길지 확인
- 옮길 위치, 방향, 색을 반환
- 제자리일 경우 None과 방향을 반환
- where가 반환한 위치가 None이면, 방향만 바꿔줌 - 2. 누굴(who) 옮길지 확인
- chess에서 말의 위치 확인
- 옮길 체스(위까지 포함)를 리스트 슬라이싱으로 가져옴 (me)
- 원래 위치는 리스트 슬라이싱으로 제거
- color에 따라 reverse - 3. pos 업데이트
- 옮길 말의 pos를 하나씩 업데이트 - 4. 종료 확인
- 옮겨진 말의 위치에 4개 이상 쌓이면 종료
다른 사람이 작성한 코드
None
- 강한 구현문제로 다른 코드를 참고하지 않음
기억해야할 것
- 주석 작성하기
- 파이썬으로 바꾸면서 코드 작성이 편해짐
- 작성이 편해지면서 주석을 작성하던 습관이 사라짐
- 디버깅시 주석이 있으면 더 빨리 위치를 파악할 수 있음
'코딩테스트' 카테고리의 다른 글
[백준][구현] 연구소 3 (0) | 2022.04.29 |
---|---|
[백준][구현] 게리멘더링 2 (0) | 2022.04.28 |
[백준][구현] 원판 돌리기 (0) | 2022.04.28 |
[백준][구현] 주사위 윷놀이 (0) | 2022.04.28 |
[백준][구현] 모노미노도미노 (0) | 2022.04.27 |