[파이썬] 백준 #1063 킹

Seori·2022년 8월 2일
0

백준

목록 보기
1/8

애증의 체스판 문제 도전♟


문제

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

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

R : 한 칸 오른쪽으로
L : 한 칸 왼쪽으로
B : 한 칸 아래로
T : 한 칸 위로
RT : 오른쪽 위 대각선으로
LT : 왼쪽 위 대각선으로
RB : 오른쪽 아래 대각선으로
LB : 왼쪽 아래 대각선으로
체스판에는 돌이 하나 있는데, 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킨다. 아래 그림을 참고하자.

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

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

입력

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

A1 A2 5
B
L
LB
RB
LT

출력

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

A1
A2

풀이 과정

체스판의 말을 각 방향으로 이동하는 문제를 베이스로 8방향 이동과 돌의 위치를 신경써야 하는 응용 문제이다.

1. 입력 값 받기

King, Stone, N = input().split()

King, Stone, N을 input().split()으로 입력받는다.
문제에서 킹과 돌의 위치를 영문+숫자 형식으로 주어졌는데,
위치 이동을 쉽게 계산할 수 있도록 숫자 형식으로 바꿔주려고 한다.

King = list(King)
Stone = list(Stone)
King_x = ord(King[0])
King_y = int(King[1])
Stone_x = ord(Stone[0])
Stone_y = int(Stone[1])
N = int(N)

그래서 King과 Stone을 list형으로 바꾸어 (x, y) 좌표를 분리하고,
아스키(ASCII) 코드 변환으로 (x, y) 좌표를 숫자형으로 바꾸었다.
N도 마찬가지로 밑에서 사용하기 위해 int형으로 바꿔주었다.

2. 이동 방향 설정하기

문제를 처음 봤을 때는 if문을 나열하여 방향을 설정했지만...
지난 번에 풀이를 보고 간단한 방법을 배웠다.

direction = ['R', 'L', 'B', 'T', 'RT', 'LT', 'RB', 'LB']
dx = [1, -1, 0, 0, 1, -1, 1, -1]
dy = [0, 0, -1, 1, 1, 1, -1, -1]

for i in range(N):
    move = input()
    for j in range(len(direction)):
        if direction[j] == move:
            x = King_x + dx[j]
            y = King_y + dy[j]

위와 같이 각 방향과 dx, dy list를 만들면 쉽게 활용이 가능하다.
input이 direction의 j번째에 해당한다면, dx[j]와 dy[j]가 작동한다.

3. 조건 적용하기

2번까지의 코드에 이어 문제 조건을 적용한다.
이 문제의 핵심이다.

for i in range(N):
    move = input()
    for j in range(len(direction)):
        if direction[j] == move:
            x = King_x + dx[j]					-------------- (a)
            y = King_y + dy[j]
            if x < 65 or x > 72 or y < 1 or y > 8:		------ (b)
                continue
            elif x == Stone_x and y == Stone_y:			------ (c)
                sx = Stone_x + dx[j]				---------- (d)
                sy = Stone_y + dy[j]
                if sx < 65 or sx > 72 or sy < 1 or sy > 8:	-- (e)
                    continue
                else:								---------- (f)
                    Stone_x, Stone_y = sx, sy
                    King_x, King_y = x, y
            else:									---------- (g)
                King_x, King_y = x, y

(a) 킹이 이동할 장소를 (x, y)로 설정한다.
(b) 만약 (x, y)가 체스판의 범위를 벗어난다면, continue
(c) 만약 (x, y)가 돌의 위치와 겹쳐진다면
(d) 돌이 이동할 위치를 (sx, sy)로 설정한다.
(e) 만약 (sx, sy)가 체스판의 범위를 벗어난다면, continue
(f) 범위를 벗어나지 않는다면, 돌은 (sx, sy)로 이동. 킹은 (x, y)로 이동.
(g) (x, y)가 체스판을 벗어나지도 않고 돌과 겹치지도 않는다면, 킹은 (x, y)로 이동.

4. 출력하기

ax = chr(King_x)
ay = str(King_y)
bx = chr(Stone_x)
by = str(Stone_y)
print(ax + ay)
print(bx + by)

출력을 위해 x 좌표는 다시 문자로, y 좌표는 str 형태로 바꿔준다.
print 함수로 알맞은 값을 출력하였다.

- 답안

King, Stone, N = input().split()
King = list(King)
Stone = list(Stone)
King_x = ord(King[0])
King_y = int(King[1])
Stone_x = ord(Stone[0])
Stone_y = int(Stone[1])
N = int(N)

direction = ['R', 'L', 'B', 'T', 'RT', 'LT', 'RB', 'LB']
dx = [1, -1, 0, 0, 1, -1, 1, -1]
dy = [0, 0, -1, 1, 1, 1, -1, -1]

for i in range(N):
   move = input()
   for j in range(len(direction)):
       if direction[j] == move:
           x = King_x + dx[j]
           y = King_y + dy[j]
           if x < 65 or x > 72 or y < 1 or y > 8:
               continue
           elif x == Stone_x and y == Stone_y:
               sx = Stone_x + dx[j]
               sy = Stone_y + dy[j]
               if sx < 65 or sx > 72 or sy < 1 or sy > 8:
                   continue
               else:
                   Stone_x, Stone_y = sx, sy
                   King_x, King_y = x, y
           else:
               King_x, King_y = x, y

ax = chr(King_x)
ay = str(King_y)
bx = chr(Stone_x)
by = str(Stone_y)
print(ax + ay)
print(bx + by)

*모든 문제의 저작권은 백준 온라인 저지(https://www.acmicpc.net/) 원작자에게 있습니다.
백준 1063번(https://www.acmicpc.net/problem/1063)

profile
뭐든 만들고 싶은 개미 개발자

0개의 댓글