728x90
게임 개발
1) 문제 해결 아이디어
전형적인 시뮬레이션 문제
방향을 설정해서 이동하는 문제 유형에서는 dx, dy라는 별도의 리스트를 만들어 방향을 정하는 것이 좋음
2차원 리스트 선언시 리스트 컴프리헨션을 이용하는 것이 좋음
2) 소스코드
(풀이1) 나의 풀이
현재 방향 기준에서 왼쪽, 반대(후진) 방향을 리스트로 만듦
n, m = map(int, input().split()) # 맵 크기
a, b, d = map(int, input().split()) # 시작 좌표, 방향
# n * m 맵 입력
# 0: 육지, 1: 바다, 2: 가본 곳
arr = [list(map(int, input().split())) for _ in range(n)]
x, y = a, b # 현재 위치
arr[x][y] = 2 # 현재 위치는 가본 곳으로 표시
cnt = 1 # 방문한 칸의 수(현재 위치 가봄 표시)
turn = 0 # 회전 횟수
directions = [0, 1, 2, 3] # 북, 동, 남, 서
# 북, 동, 남, 서 기준 방향 설정
left = [(0, -1), (-1, 0), (0, 1), (1, 0)]
back = [(1, 0), (0, -1), (-1, 0), (0, 1)]
# 시뮬레이션 시작
while True:
#print(d, turn)
# 4방향 모두 이미 가본칸/바다(4번 돌아 제자리면)
if(turn == 4):
nx = x + back[d][0]
ny = y + back[d][1]
# 바다가 아니면 후진
if(arr[nx][ny] != 1):
# 한칸 후진
x, y = nx, ny
arr[x][y] = 2 # 다녀옴 표시
turn = 0
continue
else:
# 바다이면 멈춤(탈출 조건)
break
# 1. 현재 방향 기준 왼쪽 방향 좌표 찾기
nx = x + left[d][0]
ny = y + left[d][1]
# 왼쪽 칸이 육지이면(바다/가본 곳 아니면)
if(arr[nx][ny] == 0):
# 왼쪽 방향으로 회전한 다음 한 칸 전진
d = directions[(d + 3) % 4] # 왼쪽 방향으로 회전
x, y = nx, ny # 한 칸 전진
arr[x][y] = 2 # 다녀옴 표시
cnt += 1 # 방문한 칸 횟수 세기
turn = 0
else:
# 왼쪽 방향으로 회전
d = directions[(d + 3) % 4]
turn += 1 # 회전 횟수 1 증가
# 1단계로 돌아감
continue
print(cnt)
'''
# 맵 확인
for i in range(n):
print(arr[i])
'''
(풀이2) 책 풀이
기본적인 아이디어는 비슷하지만 왼쪽으로 회전 하는 함수를 만들었다.
힘수 내에서 global 키워드를 사용해 전역변수 direction을 사용한다는 점을 주의할 것
시작 지점 방문표시 해주는 것을 잊지말아야한다.
n, m = map(int, input().split()) # 맵 크기
x, y, d = map(int, input().split()) # 현재 좌표, 방향(0, 1, 2, 3)
# n*m 맵 정보(0: 육지, 1: 바다, 2: 가봄)
arr = [list(map(int, input().split())) for _ in range(n)]
cnt = 1 # 현재 방문 횟수를 1로 초기화(시작 지점 체크)
turn = 0 # 회전 횟수
arr[x][y] = 2 # 시작 지점 방문 표시
# 북, 동, 남, 서
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
# 왼쪽 회전 함수
def turn_left():
global d # 현재 방향
d -= 1 # 왼쪽 회전
if(d == -1): # 인덱스 아웃되는 경우 처리
d = 3
# 시뮬레이션 시작
while True:
# 왼쪽 회전
turn_left()
# 검사할 칸(앞) 좌표
nx = x + dx[d]
ny = y + dy[d]
# 안가본 칸이면 전진
if(arr[nx][ny] == 0):
# 앞으로 1칸 이동
x, y = nx, ny
arr[x][y] = 2 # 방문 표시
cnt += 1 # 방문 횟수 카운팅
turn = 0 # 회전 횟수 초기화(이동했으므로)
continue
else:
turn += 1 # 회전 횟수 카운팅
# 4방향 모두 가봤거나 바다이면 후진
if(turn == 4):
# 검사할 칸(뒤) 좌표
nx = x - dx[d]
ny = y - dy[d]
# 뒤로 갈 수 있으면(바다 아니면)
if(arr[nx][ny] != 1):
# 뒤로 1칸 이동 (이전에 왔던 칸이므로 방문 횟수 카운팅 하지 않음)
x, y = nx, ny
arr[x][y] = 2
turn = 0 # 회전 횟수 초기화
# 뒤로 갈 수 없으면
else:
# 탈출
break
turn = 0
print(cnt) # 총 방문 칸 수
728x90
'[Python]알고리즘 > 이코테 2021' 카테고리의 다른 글
[DFS/BFS] BFS 예제 (0) | 2022.03.29 |
---|---|
[DFS/BFS] DFS 예제 (0) | 2022.03.29 |
[구현] ▲ 문제4 - 문자열 재정렬 (0) | 2022.03.18 |
[구현] 문제3 - 왕실의 나이트 (0) | 2022.03.18 |
[구현] 문제2 - 시각 (0) | 2022.03.18 |