일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- Python
- storybook
- 피보나치 함수
- next-auth
- interaction test
- 리팩토링
- 프로그래머스
- useEffect
- Github Actions
- custom hook
- typescript
- ZOD
- 백준
- Props Drilling
- React-hook-form
- 이메일 인증
- visual test
- React.memo
- Flutter
- 사탕게임
- suffixicon
- Vanilla JavaScript
- react
- next.js
- locale data
- kakao blind recruitment
- TextFormField
- context api
- javascript
- useMemo
- Today
- Total
Dev Diary
[백준] 1063 킹 본문
문제 이해하기
핵심 1: 킹과 돌 2개의 물체가 있다.
핵심 2: 아래와 같은 명령으로 킹의 움직임을 제어할 수 있다.
- R : 한 칸 오른쪽으로
- L : 한 칸 왼쪽으로
- B : 한 칸 아래로
- T : 한 칸 위로
- RT : 오른쪽 위 대각선으로
- LT : 왼쪽 위 대각선으로
- RB : 오른쪽 아래 대각선으로
- LB : 왼쪽 아래 대각선으로
핵심 3: 주어진 명령을 이용해 킹을 움직이다가 체스판 위에 놓여있는 돌과 같은 위치에 놓이게 된다면(겹쳐진다면) 방금 킹이 이동했던 방향으로 돌도 이동시킨다.
핵심 4: 킹과 돌 모두 체스판 범위인 8x8을 벗어나게 되는 상황이 발생한다면, 해당 상황을 발생하게한 이동을 무르고 건너뛴다.
내가 문제를 읽으며 중요하다고 생각한 부분은 이정도였고, 이 중에서도 핵심 3과 4를 신경써가며 구현해야겠다는 생각을 했다.
풀이
실패한 코드 보기
import sys
input=sys.stdin.readline
x = [1, -1, 0, 0, 1, -1, 1, -1]
y = [0, 0, -1, 1, 1, 1, -1, -1]
ctrl = ['R', 'L', 'B', 'T', 'RT', 'LT', 'RB', 'LB']
pos_king, pos_stone, N = map(str, input().split())
pos_king_x = ord(pos_king[0])
pos_king_y = int(pos_king[1])
pos_stone_x = ord(pos_stone[0])
pos_stone_y = int(pos_stone[1])
for _ in range(int(N)):
move = ctrl.index(input().rstrip())
check_king_x = pos_king_x + x[move]
check_king_y = pos_king_y + y[move]
if check_king_x < 65 or check_king_x > 72 or check_king_y < 1 or check_king_y > 8:
continue
# 여기가 문제였다! 모서리에만 집중했다 그러면 안되는데
if check_king_x == pos_stone_x and check_king_y and pos_stone_y:
if (pos_stone_x==65 or pos_stone_x==72) and (pos_stone_y==1 or pos_stone_y==8):
continue
pos_king_x = check_king_x
pos_king_y = check_king_y
if pos_king_x == pos_stone_x and pos_king_y == pos_stone_y:
check_stone_x = pos_stone_x + x[move]
check_stone_y = pos_stone_y + y[move]
if check_stone_x < 65 or check_stone_x > 72 or check_stone_y < 1 or check_stone_y > 8:
continue
pos_stone_x = check_stone_x
pos_stone_y = check_stone_y
print(chr(pos_king_x) + str(pos_king_y), chr(pos_stone_x) + str(pos_stone_y), sep='\n')
성공한 코드
import sys
input=sys.stdin.readline
# 이동 가능한 위치와 명령을 각각 x, y, ctrl 배열에 저장해둔다
# 만약 'B'를 입력받으면 B는 index 2에 있으므로 x, y배열에서 index 2에 해당하는
# x=0, y=-1이 수행되어 아래로 이동하게 된다
x = [1, -1, 0, 0, 1, -1, 1, -1]
y = [0, 0, -1, 1, 1, 1, -1, -1]
ctrl = ['R', 'L', 'B', 'T', 'RT', 'LT', 'RB', 'LB']
pos_king, pos_stone, N = map(str, input().split())
# 편리한 계산을 위해 입력받은 알파벳을 아스키코드를 이용해 숫자로 변환한다
pos_king_x = ord(pos_king[0])
pos_king_y = int(pos_king[1])
pos_stone_x = ord(pos_stone[0])
pos_stone_y = int(pos_stone[1])
for _ in range(int(N)):
# 입력받은 명령의 index를 가져옴
move = ctrl.index(input().rstrip())
# 이동 가능한 위치인지 검사하기 위해 킹의 이동을 새로운 변수에 저장한다
check_king_x = pos_king_x + x[move]
check_king_y = pos_king_y + y[move]
# 킹이 체스판 범위를 넘어서는 경우인지 검사
if check_king_x < 65 or check_king_x > 72 or check_king_y < 1 or check_king_y > 8:
continue
# 이동 가능한 범위였다면 실제 킹의 위치를 이동한 위치로 변경한다
pos_king_x = check_king_x
pos_king_y = check_king_y
# 킹이랑 돌이 같은 위치에 서게 되는 경우
if pos_king_x == pos_stone_x and pos_king_y == pos_stone_y:
# 돌도 마찬가지로 이동 가능한 위치인지 검사하기 위해 돌의 이동을 새로운 변수에 저장한다
check_stone_x = pos_stone_x + x[move]
check_stone_y = pos_stone_y + y[move]
# 돌이 체스판 범위를 벗어나는 경우(이동 불가능)
if check_stone_x < 65 or check_stone_x > 72 or check_stone_y < 1 or check_stone_y > 8:
# 킹을 이전 위치로 돌려놈 (여기가 추가한 부분)
# 즉, 이동했던 방향의 반대로 다시 이동시킨다
pos_king_x -= x[move]
pos_king_y -= y[move]
continue
# 이동 가능한 범위였다면 실제 돌의 위치를 이동한 위치로 변경한다
pos_stone_x = check_stone_x
pos_stone_y = check_stone_y
# 최종적인 킹과 돌의 위치를 출력한다
print(chr(pos_king_x) + str(pos_king_y), chr(pos_stone_x) + str(pos_stone_y), sep='\n')
정리하자면, 내가 헤맸던 곳은 돌이 체스판의 끝에 도달해 더 이상 움직일 수 없는 상태가 되었을 때, 다음 명령에서 킹이 움직일 수 없는 상태가 된 돌이 있는 자리로 이동하려고 하면 돌은 더는 이동할 수 없으므로 해당 명령은 수행될 수 없기 때문에 이것을 어떻게 처리해야하냐는 부분이였는데, 그냥 쉽게 생각해 다시 킹을 이전 위치로 되돌려 놓으면 되는 문제였다.
느낀점
아직 내 수준에서 한번 쓱 읽고 만만하게 봤던 문제였던것 같다. 특히 왠지 모르겠지만 돌이 체스판의 모서리인 A1, A8, H1, H8에 있으면서 킹이 그 옆에 딱 붙어있는 경우에만 돌도 킹도 모두 막혀서 이동할 수 없다는 생각에 틀어박혀 있던것이 이 문제에 시간을 쏟은 제일 큰 오류였다. 왜 모서리에만 그렇게 집착했을까? 돌이 A7에 있고 킹이 B7에 있는 경우에 'L' 명령을 받아도 둘 다 막혀서 이동할 수 없고 돌이 F1에 있고 킹이 E2에 있는 경우에 'RB' 명령을 받아도 둘 다 막혀서 이동할 수 없다는 것을 뒤늦게 깨달았다. (^-^)
모서리에만 집착하면서 이런 이상한 코드를 추가했는데
if check_king_x == pos_stone_x and check_king_y and pos_stone_y:
if (pos_stone_x==65 or pos_stone_x==72) and (pos_stone_y==1 or pos_stone_y==8):
continue
이렇게 모서리에만 집착했던 이유가 코드를 완성했다고 생각하고 테스트 케이스를 넣었을 때 틀렸던 케이스가 모두 돌이 모서리에 있는 경우였기 때문인것 같다. 다음부터는 주어진 케이스에만 집중해서 코드를 구현하려고 하지 말고, 더욱 넓게 보는 습관을 길러야겠다.
'Algorithms' 카테고리의 다른 글
[백준] 10026 적록색약 (0) | 2023.05.25 |
---|---|
[프로그래머스] 2018 KAKAO BLIND RECRUITMENT [1차] 비밀지도 (0) | 2023.05.23 |
[프로그래머스] 자릿수 더하기 (0) | 2023.05.22 |
[프로그래머스] 달리기 경주 (0) | 2023.05.22 |
[백준] 3085 사탕 게임 (1) | 2023.05.21 |