-
[BOJ/16236] 아기 상어 - 풀이 및 코드백준 알고리즘/Problems 2023. 8. 26. 00:41
16236번: 아기 상어
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가
www.acmicpc.net
흔히 아는 백상아리 상어는 너무 무섭네요... 귀여운 상어로 대체!! 문제
풀이
구현 문제로, 요구사항을 정리하면 다음과 같습니다.
아기 상어는 먹을 수 있는 물고기가 없으면 프로그램을 종료하고 정답을 출력한다.
정답은 아기 상어가 물고기를 먹으며 소모한 시간(초)이다.
아기 상어가 먹을 수 있는 물고기를 찾는 방법은 다음과 같다.
1. 현재 아기 상어의 위치에서 BFS를 진행한다.
2. BFS를 진행하며 아기 상어의 크기보다 큰 물고기는 통과할 수 없다. (큐에 삽입 X)
3. BFS를 진행하며 아기 상어의 크기보다 작거나 같은 물고기는 거리를 표시해둔다. (거리 갱신 및 큐 삽입)
4. 위 BFS 결과에서 가장 거리가 가까운 물고기를 골라 거리만큼 정답을 증가시키고 아기 상어의 위치를 그 물고기의 위치로 바꾼다.
5. 위 BFS 결과에서 먹을 수 있는 물고기가 없다면 프로그램을 종료한다.로직은 굉장히 단순합니다. BFS를 진행하여 먹을 수 있는 물고기를 식별하고 그 중 거리가 가장 가까우며 좌표가 좌상단에 가까운 물고기를 골라 해당 위치로 가는 비용을 정답에 계속 더해가면 되는 문제입니다. 하지만 신경써야할 것이 꽤 많은데 다음과 같은 것들을 신경써서 코드를 작성하면 큰 어려움 없이 문제를 푸실 수 있습니다.
1. 먹은 물고기는 더이상 먹으면 안된다. 따라서 그것을 식별할 정보가 필요하다.
2. 물고기를 먹은 뒤 해당 위치로 이동한다. 따라서 BFS를 진행할 때 시작 위치가 계속 바뀐다.
3. 물고기를 먹은 뒤 먹은 물고기의 개수가 현재 물고기의 크기와 같아지면 상어의 크기가 1씩 커진다.위 주의사항을 잘 지키며 구현해내면 큰 무리없이 풀 수 있다.
코드
BOJ 코드 치팅은 제재 대상입니다.
더보기import sys from collections import deque input = sys.stdin.readline INT_MAX = sys.maxsize n = int(input().rstrip()) grid = [list(map(int, input().rstrip().split())) for _ in range(n)] dirs = ((1, 0), (-1, 0), (0, 1), (0, -1)) # 최초의 상어 위치 및 물고기 정보 기록 r, c = 0, 0 for i in range(n): flag = False for j in range(n): if grid[i][j] == 9: r, c = i, j grid[i][j] = 0 flag = False break if flag: break def bfs(r, c): global dists, visited, curr_size, eatable_fishes, eaten_fishes q = deque() q.append((r, c)) cost = 0 while q: cost += 1 for _ in range(len(q)): i, j = q.popleft() for di, dj in dirs: ni, nj = i + di, j + dj if ni < 0 or nj < 0 or ni >= n or nj >= n: continue # 자신보다 작거나 같으면 통과 가능 if not visited[ni][nj] and curr_size >= grid[ni][nj]: visited[ni][nj] = True dists[ni][nj] = cost q.append((ni, nj)) # 먹지 않았으며 먹을 수 있다면 기록 if grid[ni][nj] != 0 and curr_size > grid[ni][nj] and (ni, nj) not in eaten_fishes: eatable_fishes.append((cost, (ni, nj))) ans = 0 ate_cnt = 0 curr_size = 2 eaten_fishes = set() while True: # 상어 위치에서 BFS 진행하여 물고기 정보 갱신 visited = [[False for _ in range(n)] for _ in range(n)] dists = [[INT_MAX for _ in range(n)] for _ in range(n)] visited[r][c] = True dists[r][c] = 0 eatable_fishes = [] bfs(r, c) # 먹을 수 있는 물고기를 오름차순 정렬 (비용, row, column) eatable_fishes.sort(key=lambda x: [x[0], x[1][0], x[1][1]]) if eatable_fishes: cost, location = eatable_fishes[0] i, j = location ans += cost ate_cnt += 1 eaten_fishes.add((i, j)) r, c = i, j else: break # 섭취 후 크기 증가 if ate_cnt == curr_size: curr_size += 1 ate_cnt = 0 print(ans)
참고자료
https://highlaw00-dev.tistory.com/36
[알고리즘] 시뮬레이션 - dx, dy 기법
목표 시뮬레이션 문제를 해결할 때 사용할 수 있는 dx, dy 기법이 무엇인지 알아본다. 과정 시뮬레이션 문제란? 시뮬레이션 문제는 주어진 문제의 조건을 구현하여 원하는 정답을 찾는 문제이다.
highlaw00-dev.tistory.com
좌표계 문제를 풀 때 용이한 dx, dy 기법을 포스팅 해두었습니다.
'백준 알고리즘 > Problems' 카테고리의 다른 글
[BOJ/2579] 계단 오르기 - 풀이 및 코드 (0) 2023.09.17 [BOJ/1016] 제곱 ㄴㄴ 수 - 풀이 및 코드 (0) 2023.09.03 [BOJ/1005] ACM Craft - 풀이 및 코드 (런타임 에러 해결법) (0) 2023.08.22 [BOJ/1504] 특정한 최단 경로 - 풀이 및 코드 (0) 2023.08.22 [BOJ/1516] 게임 개발 - 풀이 및 코드 (0) 2023.08.19