코딩테스트

[백준][구현] 새로운 게임 2

pythaac 2022. 4. 28. 22:12
BAEKJOON Online Judge(BOJ) 문제입니다.

https://www.acmicpc.net/

 

Baekjoon Online Judge

Baekjoon Online Judge 프로그래밍 문제를 풀고 온라인으로 채점받을 수 있는 곳입니다.

www.acmicpc.net

 

문제

https://www.acmicpc.net/problem/17837

 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하

www.acmicpc.net

 

내가 작성한 코드

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 격자 밖인 경우
      - 방향은 바꿔줘야함
      - 다른 말이 데리고 나갈 경우, 움직일 수 있으면, 바뀌던 방향으로 진행해야함
  • 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