본문 바로가기
Computer Science/Algorithm

[구름톤 챌린지] Day10 : GameJam

by 유우석 2023. 8. 27.

입력 및 출력

소스 코드

from collections import deque

def move(y, x, d, num):
	dy, dx = 0, 0
	if d == 'D':
		dy, dx = 1, 0
	elif d == 'U':
		dy, dx = -1, 0
	elif d == 'R':
		dy, dx = 0, 1
	elif d == 'L':
		dy, dx = 0, -1
	moved = 0
	while moved < num:
		y += dy
		x += dx
		if y < 0:
			y += n
		elif y >= n:
			y -= n
		if x < 0:
			x += n
		elif x >= n:
			x -= n
		if visited[y][x]:
			return moved, -1, -1
		else:
			visited[y][x] = True
			moved += 1
	ret = (moved, y, x)
	return ret


n = int(input())
game = [tuple(map(int, input().split())) for _ in range(2)]
a = [input().strip().split() for _ in range(n)]
ans = []
for sy, sx in game:
	visited = [[False for _ in range(n)] for _ in range(n)]
	q = deque([(sy-1, sx-1)])
	visited[sy-1][sx-1] = True
	score = 1
	while q:
		y, x = q.popleft()
		num = int(a[y][x][:-1])
		d = a[y][x][-1]
		moved, ny, nx = move(y, x, d, num)
		score += moved
		if moved != num:
			break
		else:
			q.append((ny, nx))
	ans.append(score)
if ans[0] > ans[1]:
	print("goorm", ans[0])
else:
	print("player", ans[1])

문제 풀이

시작 좌표에 방문 표시를 한 후 그 좌표에 적혀있는 데이터를 해석한다. '2R'이라면 오른쪽 방향으로 2칸 이동하라는 뜻이다.

 

- 이동하는 도중에 보드 바깥으로 나가게 된다면 반대쪽의 첫번째 칸으로 이동해야한다.

- 이동하면서 밟았던 칸 개수를 세준다.

- 이동하는 중 방문한 곳을 지난다면 함수를 종료하고, 탐색도 종료해야한다.

 

move 함수에서 보드 바깥으로 나갔을 때 반대쪽의 첫 번째 칸으로 이동하게끔 했고, 이동한 칸 수와 이동된 칸 좌표값을 반환했다.

이동된 칸 수와 그 좌표에 적힌 이동해야하는 칸 수 값이 다르다면, 이동을 완전하게 완료하지 않고 move함수가 종료됐다는 뜻이므로 이를 이용하여 탐색을 종료시켰다.

 

느낀 점

그래프 탐색 문제인 듯 해서 기계적으로 deque를 받아와서 사용했는데, 덱을 굳이 사용하지 않아도 됐던 것 같다. 한 상태에서 다음 노드가 여러개 쌓이는 것이 아니기 때문에, "q.append((ny, nx)) / y, x = q.popleft()" 두 코드를 "y, x = ny, nx" 로 바꿔도 똑같이 작동할 것 같다는 생각이 든다.

이 문제를 보고 고민할 때, '이걸 직접 구현해야 한다고..? 더 좋은 방법이 있지 않을까?' 라는 생각때문에 구현하기를 주저했었는데, 이런 간단한 것들은 주저없이 직접 구현해보는 그런 실행력을 가져야겠다고 느꼈다.