python 킹(백준 BOJ 1063)


문제

8*8크기의 체스판에 왕이 하나 있다. 킹의 현재 위치가 주어진다. 체스판에서 말의 위치는 다음과 같이 주어진다. 알파벳 하나와 숫자 하나로 이루어져 있는데, 알파벳은 열을 상징하고, 숫자는 행을 상징한다. 열은 가장 왼쪽 열이 A이고, 가장 오른쪽 열이 H까지 이고, 행은 가장 아래가 1이고 가장 위가 8이다. 예를 들어, 왼쪽 아래 코너는 A1이고, 그 오른쪽 칸은 B1이다.

킹은 다음과 같이 움직일 수 있다.

  • R : 한 칸 오른쪽으로
  • L : 한 칸 왼쪽으로
  • B : 한 칸 아래로
  • T : 한 칸 위로
  • RT : 오른쪽 위 대각선으로
  • LT : 왼쪽 위 대각선으로
  • RB : 오른쪽 아래 대각선으로
  • LB : 왼쪽 아래 대각선으로

체스판에는 돌이 하나 있는데, 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킨다. 아래 그림을 참고하자.

img

입력으로 킹이 어떻게 움직여야 하는지 주어진다. 입력으로 주어진 대로 움직여서 킹이나 돌이 체스판 밖으로 나갈 경우에는 그 이동은 건너 뛰고 다음 이동을 한다.

킹과 돌의 마지막 위치를 구하는 프로그램을 작성하시오.


입력

첫째 줄에 킹의 위치, 돌의 위치, 움직이는 횟수 N이 주어진다. 둘째 줄부터 N개의 줄에는 킹이 어떻게 움직여야 하는지 주어진다. N은 50보다 작거나 같은 자연수이고, 움직이는 정보는 위에 쓰여 있는 8가지 중 하나이다.


출력

첫째 줄에 킹의 마지막 위치, 둘째 줄에 돌의 마지막 위치를 출력한다.


예제 입력 1

A1 A2 5
B
L
LB
RB
LT

예제 출력 1

A1
A2

예제 입력 2

A1 H8 1
T

예제 출력 2

A2
H8

예제 입력 3

A1 A2 1
T

예제 출력 3

A2
A3

예제 입력 4

A1 A2 2
T
R

예제 출력 4

B2
A3

예제 입력 5

A8 B7 18
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB
RB

예제 출력 5

G2
H1

예제 입력 6

C1 B1 3
L
T
LB

예제 출력 6

B2
A1


📝 풀어보기

📌 좌표에 대한 지시를 영문으로 출력하므로 딕셔너리를 사용한다.

지시에 따라 움직일 값을 키 값 쌍으로 저장한다.

킹의 위치 K, 돌의 위치 S, 움직이는 횟수 N을 입력받는다.

킹의 x,y 좌표를 영문과 숫자를 분리하여 각각 int형과 ord로 변환해서 계산 후 저장한다. 돌의 x,y 좌표도 구하는 방법은 같다.

directions = {
    # x, y 좌표
    "R": (0, 1),
    "L": (0, -1),
    "B": (1, 0),
    "T": (-1, 0),
    "RT": (-1, 1),
    "LT": (-1, -1),
    "RB": (1, 1),
    "LB": (1, -1)
}
# 킹의 위치, 돌의 위치, 움직이는 횟수
K, S, N = input().split() # A1 H8 1
kx, ky = 8 - int(K[1]), ord(K[0])-65 # 8 - 1 = 7 / A(65) - 65 = 0 (7, 0)
sx, sy = 8 - int(S[1]), ord(S[0])-65 # 8 - 2 = 6 / A(65) - 65 = 0 (0, 0)


📌 움직이는 횟수 N 동안 움직일 커맨드를 입력받는다.

dx, dy는 입력받은 커맨드 딕셔너리 값의 1번째 요소, 2번째 요소가 저장된다.

킹의 좌표+dx, dy가 체스판 범위 내에 없는 경우엔 건너뛰고 그외엔 킹의 좌표에 합산한다.

for _ in range(int(N)): # 움직이는 횟수
    cmd = input().strip()
    dx, dy = directions[cmd] # T (-1, 0)
    # 킹이 체스판 범위를 벗어나는 경우
    if not (0 <= kx+dx < 8 and 0 <= ky+dy < 8):
        continue # 건너뜀
    kx += dx # 킹 x 좌표에 커맨드 좌표를 더함
    ky += dy # 킹 y 좌표에 커맨드 좌표를 더함


📌 돌의 좌표+ dx, dy가 체스판 범위 밖을 벗어나는 경우에는 킹의 좌표에 있는 커멘드 좌표를 무르고 건너뛴다.

그외엔 돌의 좌표에 dx, dy를 합산한다.

마지막으로 다시 좌표값을 체스판에 맞게 표시해야 하므로 형변환으로 각각의 x, y 좌표를 변환하고 출력한다.

        # 돌의 좌표가 체스판을 벗어나는 경우
        if not (0 <= sx+dx < 8 and 0 <= sy+dy < 8):
            kx -= dx # 킹의 좌표에 커맨드 좌표를 무른다
            ky -= dy # 킹의 좌표에 커맨드 좌표를 무른다
            continue # 건너뜀
        sx += dx # 돌의 x좌표에 커맨드 좌표를 넣는다
        sy += dy # 돌의 y좌표에 커맨드 좌표를 넣는다
        
print(chr(65+ky)+str(8-kx)) # 숫자 A에 킹의 y 좌표를 더한 값 + 8에 킹의 x좌표를 뺀 값
print(chr(65+sy)+str(8-sx)) # 숫자 A에 돌의 y 좌표를 더한 값 + 8에 돌의 x좌표를 뺀 값


전체코드

directions = {
    # x, y 좌표
    "R": (0, 1),
    "L": (0, -1),
    "B": (1, 0),
    "T": (-1, 0),
    "RT": (-1, 1),
    "LT": (-1, -1),
    "RB": (1, 1),
    "LB": (1, -1)
}
# 킹의 위치, 돌의 위치, 움직이는 횟수
K, S, N = input().split() # A1 H8 1
kx, ky = 8 - int(K[1]), ord(K[0])-65 # 8 - 1 = 7 / A(65) - 65 = 0 (7, 0)
sx, sy = 8 - int(S[1]), ord(S[0])-65 # 8 - 2 = 6 / A(65) - 65 = 0 (0, 0)
for _ in range(int(N)): # 움직이는 횟수
    cmd = input().strip()
    dx, dy = directions[cmd] # T (-1, 0)
    # 킹이 체스판 범위를 벗어나는 경우
    if not (0 <= kx+dx < 8 and 0 <= ky+dy < 8):
        continue # 건너뜀
    kx += dx # 킹 x 좌표에 커맨드 좌표를 더함
    ky += dy # 킹 y 좌표에 커맨드 좌표를 더함
    if (kx, ky) == (sx, sy): # 킹의 좌표와 돌의 좌표가 같을경우 
        # 돌의 좌표가 체스판을 벗어나는 경우
        if not (0 <= sx+dx < 8 and 0 <= sy+dy < 8):
            kx -= dx # 킹의 좌표에 커맨드 좌표를 무른다
            ky -= dy # 킹의 좌표에 커맨드 좌표를 무른다
            continue # 건너뜀
        sx += dx # 돌의 x좌표에 커맨드 좌표를 넣는다
        sy += dy # 돌의 y좌표에 커맨드 좌표를 넣는다

print(chr(65+ky)+str(8-kx)) # 숫자 A에 킹의 y 좌표를 더한 값 + 8에 킹의 x좌표를 뺀 값
print(chr(65+sy)+str(8-sx)) # 숫자 A에 돌의 y 좌표를 더한 값 + 8에 돌의 x좌표를 뺀 값

관심있을 포스팅