[백준 1063] 킹

코뉴·2022년 1월 27일
0

백준🍳

목록 보기
81/149
post-custom-banner

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

🥚문제


🥚입력/출력


🍳코드

import sys
from collections import deque
input = sys.stdin.readline


def location(string):
    # A2 -> board[7][1]로 쓸 수 있게 변환
    row = 9 - int(string[1])
    col = ord(string[0]) - 64
    return (row, col)


def location_reverse(row, col):
    # board[7][1] -> A2로 변환
    number = 9 - row
    alphabet = chr(64 + col)
    return alphabet+str(number)


board = [[0]*9 for _ in range(9)]
# 입력
king, stone, move = input().split()
# board에 king, stone 표시
king_row, king_col = location(king)
stone_row, stone_col = location(stone)
board[king_row][king_col] = 1  # 1 = king
board[stone_row][stone_col] = 2  # 2 = stone
# move 정보 받기
move_cmd = {'R': (0, 1), 'L': (0, -1), 'B': (1, 0), 'T': (-1, 0),
            'RT': (-1, 1), 'LT': (-1, -1), 'RB': (1, 1), 'LB': (1, -1)}
moves = deque([])
for _ in range(int(move)):
    moves.append(move_cmd[input().strip()])


def move_king(r, c):
    while moves:
        r_move, c_move = moves.popleft()
        new_r = r + r_move
        new_c = c + c_move

        if test_safe_inex(new_r, new_c):
            # 돌과 같은 곳으로 이동한다면
            if board[new_r][new_c] == 2:
                # 돌을 같은 방향으로 한 칸 이동하는데,
                # 이 때 돌의 인덱스 체크
                stone_r = new_r + r_move
                stone_c = new_c + c_move
                if test_safe_inex(stone_r, stone_c):
                    # 이동
                    board[stone_r][stone_c] = 2
                    board[new_r][new_c] = 1
                    board[r][c] = 0  # 이전 위치 비워주기
                    # r, c 업데이트
                    r = new_r
                    c = new_c
                # safe_index가 아니라면 아무 동작도 하지 않음
                else:
                    continue
            # 빈칸으로 이동한다면
            else:
                board[new_r][new_c] = 1
                board[r][c] = 0
                # r, c 업데이트
                r = new_r
                c = new_c
        # safe_index가 아니라면 아무 동작도 하지 않음
        else:
            continue
        """
        print('='*15, r_move, c_move, '='*15)
        for row in board:
            print(row)
        """


def test_safe_inex(r, c):
    if 1 <= r <= 8 and 1 <= c <= 8:
        return True
    return False


def get_king_loc():
    for r in range(1, 9):
        for c in range(1, 9):
            if board[r][c] == 1:
                return (r, c)


def get_stone_loc():
    for r in range(1, 9):
        for c in range(1, 9):
            if board[r][c] == 2:
                return (r, c)


# move_king 실행
move_king(king_row, king_col)
# king의 위치, stone의 위치를 출력
king_row, king_col = get_king_loc()
stone_row, stone_col = get_stone_loc()
print(location_reverse(king_row, king_col))
print(location_reverse(stone_row, stone_col))

🧂아이디어

구현

  • 킹의 움직임을 나타내는 'R', 'L', 'B' 등의 입력은 move_cmd라는 딕셔너리를 사용해서 쉽게 좌표상의 움직임으로 변환할 수 있게 했다.
  • def location(string)
    • 문제에서 말의 위치가 알파벳+숫자 조합으로 주어지는데, 알파벳은 열을 상징하고 숫자는 행을 상징한다.
    • 따라서 이를 2차원 리스트의 index로 적절히 나타내주기 위해서 알파벳+숫자 str를 인자로 받고 row, col을 나타내는 index를 리턴해주는 함수를 만들었다.
  • def location_reverse(row, col)
    • row, col을 나타내는 index를 다시 알파벳+숫자 문자열로 바꿔주기 위한 함수이다. 정답 출력 시 사용한다.
  • def move_king(r, c)
    • king 말의 움직임을 나타내는 함수이다.
    • 인자 r, c는 초기 king의 위치이다.
    • new_r, new_c는 king이 이동하려고 하는 위치이다.
    • new_r, new_c가 보드를 벗어나지 않는다면
      • 돌과 같은 곳으로 이동하는지 체크한다.
      • 돌과 같은 곳으로 이동한다면
        • 돌도 같은방향으로 이동했을 때, 돌이 보드를 벗어나지 않는지 체크한다.
        • 돌이 보드를 벗어나지 않는다면 돌, king을 움직이고 이전에 king이 있었던 위치를 비워준다. 마지막으로, 다음 움직임을 위해 r과 c를 업데이트해준다.
        • 돌이 보드를 벗어난다면 아무 동작도 하지 않는다.
      • 돌과 같은 곳으로 이동하지 않는다면
        • king을 움직이고 이전에 king이 있었던 위치를 비워준다. 마지막으로, 다음 움직임을 위해 r과 c를 업데이트해준다.
    • new_r, new_c가 보드를 벗어난다면 아무 동작도 하지 않는다
  • def test_safe_index(r, c)
    • r, c라는 인덱스가 8*8 보드 안에 위치하는지 검사한다.
  • def get_king_loc(), def get_stone_loc()
    • 각각 king의 위치와 돌의 위치를 반환한다.
profile
코뉴의 도딩기록
post-custom-banner

0개의 댓글