19236.청소년상어
Updated:
Intro
- 곧 삼성 SW 역량 모의 테스트가 있어서 19236번 청소년상어 문제를 풀어보았습니다.
청소년상어
문제 설명
- 목표
- 상어가 먹을 수 있는 물고기 번호의 합의 최댓값
- 상태
- 4x4 공간
- 각 칸에는 물고기가 있고, 물고기는 번호(1~16)와 방향(상하좌우, 대각선)을 가지고 있다.
- 상어는 (0, 0)에서 시작하고, 방향은 해당 칸에 있는 물고기의 방향을 따른다.
- 물고기 이동
- 상어가 이동한 뒤, 모든 물고기가 번호 순으로 이동한다. (번호가 작은 순부터 이동)
- 물고기는 한 칸만 이동 가능
- 상어가 이동할 수 있는 칸 1. 물고기가 있는 칸 2. 빈 칸
- 상어가 이동할 수 없는 칸 1. 상어 존재 2. 공간 경계 넘는 칸
- 이동할 수 있는 칸이 나올 때까지 반시계 방향 45도 회전(최대 7번)
- 다른 물고기가 있는 칸으로 이동할 때는 서로 위치 교환 fish1, fish2 = fish2, fish1
- 상어 이동
- 물고기 이동이 끝난 뒤, 현재 방향에 있는 모든 칸 중 물고기가 있는 칸으로 이동
- 상어는 한 번에 여러 칸 이동 가능
- 이동 중에는 물고기 먹지 않음
- 이동한 칸의 물고기를 먹고 해당 물고기의 방향을 갖는다.
- 이동할 수 있는 칸이 없으면 종료
문제 접근 방식
- 상어를 먼저 옮긴 후, 물고기 위치를 옮겨줍니다.
- 여기서, 먹을 수 있는 물고기 번호 합의 최대값을 알아야 하므로, array를 여러번 움직일 것을 고려해, deepcopy를 이용해 copy해둡니다.
- 또한, 방향을 쉽게 바꿀수 있도록 1번부터 8번까지 해당 방향의 좌표를 dictionary로 미리 만들어둡니다.
문제 답안
-
from copy import deepcopy direction = { 1: [-1, 0], 2: [-1, -1], 3: [0, -1], 4: [1, -1], 5: [1, 0], 6: [1, 1], 7: [0, 1], 8: [-1, 1] } def move_shark(i, j, direct, eaten): global arr, ans, direction backup = deepcopy(arr) move_fish() if ans < sum(eaten): ans = sum(eaten) for k in range(1, 4): # 상어의 새로운 좌표 찾기 ni = i + direction[direct][0] * k nj = j + direction[direct][1] * k # 물고기가 없다면 스킵하기 if 0 <= ni < 4 and 0 <= nj < 4: if arr[ni][nj][0] == 0: continue fish = arr[ni][nj][0] direct = arr[ni][nj][1] store = arr[i][j][1] arr[i][j][0] = 0 arr[ni][nj][0] = -1 move_shark(ni, nj, arr[ni][nj][1], eaten + [fish]) # 물고기 원상태로 되돌려놓기 arr[i][j][0] = -1 arr[ni][nj][0] = fish direct = store # ㅎ... 방향땜에 얼마나 헤맸나 ^0^ # 맵 이전으로 돌려놓기 arr = backup def move_fish(): for k in range(1, 17): # 먼저 해당 fish의 location을 찾는다 flag = False if k in eaten: continue for i in range(4): for j in range(4): if arr[i][j][0] == k: fish_i = i fish_j = j fish_direction = arr[i][j][1] flag = True break if flag: break else: continue # 물고기가 이동할 수 있는지 확인해본다. while True: ni = fish_i + direction[fish_direction][0] nj = fish_j + direction[fish_direction][1] if 0 <= ni < 4 and 0 <= nj < 4 and arr[ni][nj][0] != -1: temp_fish = arr[ni][nj] arr[ni][nj] = arr[fish_i][fish_j] arr[fish_i][fish_j] = temp_fish break else: # 만약 이동할 수 없다면 이동 방향을 1 추가한다. fish_direction +=1 if fish_direction > 8: fish_direction = fish_direction % 8 arr[fish_i][fish_j][1] = fish_direction arr = [] # 처음에 배열 만들기 for i in range(4): list1 = [] temp = list(map(int, input().split())) for j in range(4): list1.append([temp[2*j], temp[2*j+1]]) arr.append(list1) # 상어가 뭐 먹었는지 체크하기 eaten = [] eaten.append( arr[0][0][0]) ans = 0 # 상어 위치 바꾸기 arr[0][0][0] = -1 shark_i = 0 shark_j = 0 shark_dir = arr[0][0][1] move_shark(shark_i, shark_j, shark_dir, eaten) print(ans) # 메모리: 29956 KB # 시간: 88ms
Leave a comment