알고리즘/문제풀이

구현(킹 /S3) - 1063번

문승주 2022. 11. 28. 21:43
반응형

1. 문제

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

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

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

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

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

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

 

2. 입력

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

A1 A2 5
B
L
LB
RB
LT

 

 

 

 

3. 출력

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

 

4. 코드

import sys

def move(x, y, moveData):
  w, h = x, y
  for m in list(moveData):
    # R이나 L일 경우 아스키코드로 변환하여 처리
    if m == 'R':
      a = ord(x) + 1
      if a <= 72:
        x = chr(a)
      else:
        x, y = w, h
        break
    elif m == 'L':
      a = ord(x) - 1
      if a >= 65:
        x = chr(a)
      else:
        x, y = w, h
        break
    # T이나 D일 경우 정수형으로 변환하여 처리
    elif m == 'T':
      a = int(y) + 1
      if a <= 8:
        y = str(a)
      else:
        x, y = w, h
        break
    else:
      a = int(y) - 1
      if a >= 1:
        y = str(a)
      else:
        x, y = w, h
        break
  return x, y


k, s, n = list(sys.stdin.readline().split())
moveList = [sys.stdin.readline().strip() for _ in range(int(n))]

kingX, kingY = list(k)
stoneX, stoneY = list(s)
for i in range(int(n)):
  # 이동하기 전 좌표 세팅
  kX, kY = kingX, kingY
  # 이동함수 호출
  kingX, kingY = move(kingX, kingY, moveList[i])
  # 입력값과 이동한 좌표 비교
  if kingX == stoneX and kingY == stoneY:
    # 이동함수 호출
    stoneX, stoneY = move(stoneX, stoneY, moveList[i])
    # stoneX, stoneY가 이동할 수 없으면 이동하기 전 좌표를 kingX, kingY에 대입
    if kingX == stoneX and kingY == stoneY:
      kingX, kingY = kX, kY

print(kingX+kingY)
print(stoneX+stoneY)

 

5. 풀이설명

① k, s, n을 입력받는다.

 

② 이동하는 좌표가 담긴 배열 moveList를 입력받는다.

 

③ kingX, kingY / stoneX, stoneY에 킹의 좌표(k), 돌의 좌표(s)를 리스트로 변환하여 대입한다. 

 

반복문 처리중 kingX, kingY를 kx, ky에 대입한다.

 

⑤ kingX, kingY, moveList[i]를 인자로 move 함수를 호출한다.

 

⑥ w,h 에 매개변수로 받은 x,y를 다른 매개변수 이동 좌표 moveData를 리스트로 만들어 분리하고 반복문을 실행한다.

 

- m 이 'R' 인 경우

  m을 아스키코드로 변환하여 1을 더하고 72보다 작거나 같으면 x에 대입 크면  x,y에 ⑥에서 대입한 w,h 를 대입한다.

 

- m 이 'L' 인 경우

  m을 아스키코드로 변환하여 1을 더하고 65보다 크거나 같으면 x에 대입 작으면  x,y에 ⑥에서 대입한 w,h 를 대입한다.

 

- m 이 'T' 인 경우

  m을 정수형으로 변환하여 1을 더하고 8보다 작거나 같으면 y에 대입 크면  x,y에 ⑥에서 대입한 w,h 를 대입한다.

 

- m 이 'D' 인 경우

  m을 정수형으로 변환하여 1을 더하고 1보다 크거나 같으면 y에 대입 작으면  x,y에 ⑥에서 대입한 w,h 를 대입한다.

 

⑧ move 함수 결과 x, y를 반환한다.

 

⑨ 이동한 kingX, kingY와 입력받은 돌의 좌표 stoneX, stoneY가 같으면 stoneX, stoneY, moveList[i]를 인자로 move함수를 호출한다.

 

⑩ ⑨의 move함수 반환값이 기존 stoneX, stoneY와 같으면 kingX, kingY에 ④에서 대입한 이동 이전값 kX, kY를 대입한다.

 

⑪ kingX+kingY와 stoneX+stoneY를 출력한다.

 

6. 느낀점

아스키 코드를 사용하여 문제를 해결하였는데 코드가 좀 길어서 아쉽다.

반응형