ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] 백준 16236 아기 상어
    알고리즘/문제풀이 2021. 7. 24. 19:20
    728x90

    1. 문제 링크

    https://www.acmicpc.net/problem/16236

     

    16236번: 아기 상어

    N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가

    www.acmicpc.net


    2. 문제 요약

    • 아기 상어가 물고기를 먹으러 가는데 걸리는 최단 거리 구하기

    아기 상어 문제 요약 


    3. 아이디어 정리

    1. bfs로 현재 상어 위치에서 갈 수 있는 최단 거리를 찾는다. ⇒ bfs
      • 예외처리 필요: 큰 상어는 못 지나간다.
    2. 1 결과를 이용하여 가장 가까운 물고기 위치를 얻는다.
      • 예외 처리: 아기 상어보다 작은 물고기만 먹을 수 있다.
    3. 2에서 진행한 결과가 있는 경우 아기 상어 위치와 크기를 갱신 후 1번 다시 진행, 2 결과가 없는 경우 break(엄마한테 요청)

    4. 문제 풀이

    4-1. 내 풀이

    import sys
    from collections import deque
    
    dx = [0, 0, -1, 1]
    dy = [1, -1, 0, 0]
    
    def bfs(now_pos, now_size):
        """
        현재 상어 위치에서 갈 수 있는 최단 거리를 찾는다.
        """
        dq = deque()
        dq.append(now_pos)
        visit[now_pos[0]][now_pos[1]] = 1
        while dq:
            x, y = dq.popleft()
            for d in range(4):
                nx = dx[d] + x
                ny = dy[d] + y
                if nx < 0 or ny < 0 or nx >= n or ny >= n:
                    continue
                if visit[nx][ny] != 0:
                    continue
                if graph[nx][ny] > now_size:  # 큰 물고기는 못지나감
                    continue
                visit[nx][ny] = visit[x][y] + 1
                dq.append((nx, ny))
    
    def get_min_dist(now_size):
        """
        최단 거리에 있는 물고기를 찾아 거리를 얻는다.
        :param now_size: 현재 상어 크기
        :return: 상어가 이동할 좌표, 상어가 이동할 최단 거리
        """
        x, y = 0, 0
        min_dist = int(1e9)
        for i in range(n):
            for j in range(n):
                # 방문 했고, 물고기가 존재, 상어 크기보다 작은 경우 방문
                if visit[i][j] != 0 and graph[i][j] > 0 and graph[i][j] < now_size:
                    if min_dist > visit[i][j] - 1:   # 지금까지 가장 가까운 거리인 경우 저장
                        min_dist = visit[i][j] - 1
                        x = i
                        y = j
        return (x, y, min_dist)
    
    n = int(sys.stdin.readline())   # 공간의 크기
    graph = [[] for _ in range(n)]
    # visit = [[0] * n for _ in range(n)]
    
    ans = 0
    now_size = 2
    now_ate = 0
    now_pos = (0, 0)
    for i in range(n):
        arr = list(map(int, sys.stdin.readline().split()))
        now = [(i, j) for j, a in enumerate(arr) if a == 9]
        if now: now_pos = now[0]
        graph[i] = arr
    graph[now_pos[0]][now_pos[1]] = 0  # 상어의 위치는 0으로 설정
    
    while True:
        # 1. bfs로 현재 상어 위치에서 갈 수 있는 최단 거리를 찾는다.
        visit = [[0] * n for _ in range(n)]
        bfs(now_pos, now_size)
        # 2. 최단 거리에 있는 물고기를 찾아 거리를 얻는다.
        x, y, dist = get_min_dist(now_size)  # 상어가 이동한 위치, 상어 이동 거리
        if dist != int(1e9):  # 상어 이동 가능한 경우
            ans += dist
            now_pos = (x, y)            # 상어 위치 변경
            now_ate += 1                # 현재까지 먹은 물고기 더하기
            # 상어 사이즈만큼 먹은 경우 상어 사이즈 증가
            if now_ate == now_size:
                now_size += 1
                now_ate = 0
            graph[x][y] = 0             # 현재 상어의 위치 0으로 변경
        else:               # 상어 이동 불가능한 경우
            break
    print(ans)

     


    5. 결론

    • 최단 거리를 구하는 bfs 문제 but 예외 처리할 것이 많았던 문제이다. (상어 크기🦈 , 물고기 크기 🐠 등등)

     

     

     

    댓글

Designed by Tistory.