1. 문제
현민이는 게임 캐릭터가 맵 안에서 움직이는 시스템을 개발 중이다. 캐릭터가 있는 장소는 1 x 1 크기의 정사각형으로 이뤄진 N X M 크기의 직사각형으로, 각각의 칸은 육지 또는 바다이다. 캐릭 터는 동서남북 중 한 곳을 바라본다. 맵의 각 칸은 (A, B)로 나타낼 수 있고, A는 북쪽으로부터 떨어진 칸의 개수, B는 서쪽으로부터 떨 어진 칸의 개수이다. 캐릭터는 상하좌우로 움직일 수 있고, 바다로 되어 있는 공간에는 갈 수 없다. 캐릭터의 움직임을 설정하기 위해 정해 놓은 매뉴얼은 이러하다.
1. 현재 위치에서 현재 방향을 기준으로 왼쪽 방향(반시계 방향으로 90도 회전한 방향)부터 차례대로 갈 곳을 정한다.
2. 캐릭터의 바로 왼쪽 방향에 아직 가보지 않은 칸이 존재한다면, 왼쪽 방향으로 회전한 다음 왼쪽으로 한 칸을 전진한다. 왼쪽 방향에 가보지 않은 칸이 없다면, 왼쪽 방향으로 회전만 수행하고 1단계로 돌아간다.
3. 만약 네 방향 모두 이미 가본 칸이거나 바다로 되어 있는 칸인 경우에는, 바라보는 방향을 유지한 채로 한 칸 뒤로 가고 1단계로 돌아간다. 단, 이때 뒤쪽 방향이 바다인 칸이라 뒤로 갈 수 없는 경우에는 움직임을 멈춘다.
현민이는 위 과정을 반복적으로 수행하면서 캐릭터의 움직임에 이상이 있는지 테스트하려고 한다. 매뉴얼에 따라 캐릭터를 이동시킨 뒤에, 캐릭터가 방문한 칸의 수를 출력하는 프로그램을 만드시오.
입력 조건
. 첫째 줄에 맵의 세로 크기 N 과 가로 크기 M을 공백으로 구분하여 입력한다. (3 ≤ N, M S 50) - 둘째 줄에 게임 캐릭터가 있는 칸의 좌표 (A, B)와 바라보는 방향 d가 각각 서로 공백으로 구분하여 주어진다. 방향 의 값으로는 다음과 같이 4가지가 존재한다.
- 0: 북쪽 1: 동쪽 2: 남쪽 3:서쪽
2. 구현 과정
- 현재 위치를 기준으로 방문하지 않은 곳 and 육지인 곳을 찾아 이동하는 문제
- 네 방향의 방향 좌표값을 가진 dx,dy를 선언하여 for 문 4번을 돌면서 탐색하면 된다.
- 게임 캐릭터가 바라보는 방향이 이동 후에도 유지되고 있음에 유의해야 한다. 예를 들어 캐릭터가 남쪽으로 이동했다면, 북쪽에서부터 다시 반시계 방향으로 이동하는게 아니라, 남쪽 기준 반시계 방향인 동쪽에서 부터 방향을 탐색해야 한다. => 캐릭터의 방향성을 direction 변수로 저장해야 함
- 현재 바라보는 방향이 북쪽(0) 이면 차례로 3->2->1 이어야 하고, 동쪽이라면 0 -> 3 -> 2순으로 탐색 진행 해야 함.
해당 방향값들을 얻기 위해서 다음의 방식을 사용할 수 있다.
#x : 현재 방향값, nx : 탐색할 방향값
---------------------------------------
dx = [0,1,0,-1]
dy = [-1,0,1,0]
direction = 현재 방향값
for i in range(1,4):
nx = x + dx[ ( 4 + (direction - i) ) % 4]
ny = y + dy[ ( 4 + (direction - i) ) % 4]
------------------------------------
def turn_left():
global direction
direction -= 1
if diection == -1:
direction = 3
- 만약 4 방향 모두 방문이 불가능 하면 탐색을 종료한다.
3. 실수
- 방문하고 싶은 곳이 범위를 벗어났는지 확인을 먼저 한 후 방문 여부 확인하기! (안그러면 index 범위 벗어났다고 오류뜸)
- 네 방향에 대한 index값이 문제에서 주어졌음에 유의하자! ( 처음엔 내 맘대로 서쪽 = 0, 남쪽 = 1,...로 했다가 오류 찾느라 오래걸렸다.)
- for i in range(4, 1, -1) :으로 하면 i = 4,3,2,1의 순으로 for문 탐색 가넝
4. 코드
#게임 개발
#반시계 방향
dx = [0,1,0,-1]
dy = [-1,0,1,0]
#입력 받기
N,M = map(int,input().split())
x,y,direction = map(int,input().split())
board = [ 0 for _ in range(N)]
# 1: 바다 , 0 : 육지
for i in range(N):
board[i] = list(map(int,input().split()))
board[x][y] = 1 #시작 부분 방문 처리
count = 1 #캐릭터가 방문한 칸의 수. 맨 처음 포함
# 캐릭터 이동(반시계 방향)
while True:
newdirection = direction
for i in range(1,4):
nx = x + dx[ (4 + (direction - i)) % 4]
ny = y + dy[ (4 + (direction - i)) % 4]
if nx < 0 or nx >= M or ny < 0 or ny >= N or board[nx][ny] == 1 :
continue
#네 방향 중 이동할 곳을 찾음
newdirection = (4 + (direction - i)) % 4
x = nx
y = ny
board[nx][ny] = 1
break
#더 이상 이동할 수 없음
if newdirection == direction:
break
else:
direction = newdirection
count += 1
print(count)
'알고리즘' 카테고리의 다른 글
[이것이코딩테스트] 떡볶이 떡 만들기 (0) | 2021.08.17 |
---|---|
[1874]스택수열(C++) (0) | 2020.12.14 |
[Union Find] (0) | 2020.07.28 |