알고리즘/백준[baekjoon]
[baekjoon] 백준 16236번 : 아기 상어 (by python 파이썬) bfs, lambda정렬
코딩하는이씨
2022. 8. 2. 22:53
728x90
반응형
https://www.acmicpc.net/problem/16236
16236번: 아기 상어
N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가
www.acmicpc.net
정답 code
#아기 상어
from collections import deque
import sys
input = sys.stdin.readline
dx = [-1,1,0,0]
dy = [0,0,1,-1]
def bfs(x,y,shark_size):
distance = [[0]*n for _ in range(n)] #거리 저장
visit = [[0]*n for _ in range(n)] #방문 여부 저장
queue = deque()
queue.append((x,y))
visit[x][y] = 1 #방문처리
eat = [] #먹을수 있는 물고기의 좌표, 거리 저장하기 위함
while queue:
ix,iy = queue.popleft()
for i in range(4):
nx = dx[i] + ix
ny = dy[i] + iy
#새로운 좌표가 n*n공간 안에 있고 방문한적 없을때
if 0<=nx<n and 0<=ny<n and visit[nx][ny] == 0:
#물고기크기가 상어보다 작거나 같은경우
if space[nx][ny] <= shark_size:
queue.append((nx,ny))
visit[nx][ny] = 1
distance[nx][ny] = distance[ix][iy] + 1
#물고기가 있고, 물고기크기가 상어보다 작은 경우
if space[nx][ny] < shark_size and space[nx][ny] != 0:
#해당 물고기의 위치(nx,ny), 물고기까지의 최소 거리(distance) 저장
eat.append((nx,ny,distance[nx][ny]))
#특정 순서 기준으로 정렬 하기 위해 lambda함수 사용
#x[2]: 거리 / x[0]: 행 / x[1]: 열 순으로 내림차순정렬 - pop으로 꺼내기위함
return sorted(eat, key = lambda x : (-x[2],-x[0],-x[1]))
n = int(input()) #공간 크기
space = [list(map(int,input().split())) for _ in range(n)]
cnt = 0
result = 0
x,y,size = 0,0,2
for i in range(n):
for j in range(n):
if space[i][j] == 9 :
x = i
y = j
#while 1회 순환시 물고기 한마리 잡아 먹음
while 1:
#좌표에서 부터 가장 가까운 물고기 좌표, 거리 찾기
shark = bfs(x,y,size)
#더이상 먹을 물고기가 없으면 종료
if len(shark) == 0:
break
#상어보다 작은 물고기 좌표 nx,ny, 물고기까지의 최소거리 dist 로 저장
nx,ny,dist = shark.pop()
#거리 1 = 1초 // 결과에 거리 저장
result += dist
#상어있던 위치 or 잡아먹은 물고기위치 숫자 0 으로 바꿔줌
space[x][y], space[nx][ny] = 0,0
#잡아먹은 물고기 좌표 nx, ny 부터 다시 bfs 탐색하기 위해
x, y = nx,ny
#물고기 먹을때 마다 cnt 추가
cnt += 1
#상어크기와 같은 수의 물고기를 먹으면 size(크기)+ 1
if cnt == size:
size += 1
cnt = 0
print(result)
solution
애로사항은 처음에 while문에 담긴 조건사항을 모두 bfs내에서 해결하려하다보니 어느정도 틀은 잡혔는데 세부 조건들에 대해 진척이 없었다.
while문을 통해 먹을수있는 물고기가 없을때까지 가까운 거리순으로 bfs함수를 돌려줌으로써 해결할 수 밖에 없었다.
큰틀만 설명하자면 bfs함수를 통해 현재 먹을 수있는 물고기(= 자신보다 작은 크기)의 물고기의 좌표와 최단거리를
eat함수에 저장한다음 값이 여러개이면 거리/행/열 순으로 리턴해준다.
이때 lambda함수를 통해 우선순위 정렬을 해주는데 -를 붙이는 이유는 나중에 작은것부터 pop을 이용해 사용하는데
거리/행/열 순으로 가장 작은걸 오른쪽에 배치해 가장 먼저 꺼내지도록 하기 위함이다.
만약 먹은 물고기의 갯수가 크기와 같다면 상어 크기(size)를 +1 해주고
마지막으로 먹은 물고기 좌표부터 시작해주면 된다.
상세 내용은
코드가 길어 설명을 주석 처리하였다.
728x90
반응형