본문 바로가기
Problem Solving/BOJ

[Python]16236. 아기 상어

by 부르르 2019. 4. 9.

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

 

16236번: 아기 상어

N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가지고 있고, 이 크기는 자연수이다. 가장 처음에 아기 상어의 크기는 2이고, 아기 상어는 1초에 상하좌우로 인접한 한 칸씩 이동한다. 아기 상어는 자신의 크기보다 큰 물고기가 있는 칸은 지나갈 수 없고, 나머지 칸은 모두 지나갈 수 있다. 아기 상어는 자신의 크

www.acmicpc.net


 

BFS + 약간의 시뮬레이션  문제라고 생각한다.

누구는 BFS만으로도 푼다.

코드구현은 한시간 걸린듯 한데

디버깅이 너무너무너무 오래걸렸다.

원인은 tmp가 -1 이 되는 경우가 있어서였다. (참고.  # 중요. tmp = -1 일 경우 tmp 최소값으로 -1이 잡혀서 틀림)

 

테스트케이스를 스스로 만들어봤는데

3

9 2 2

2 2 3

1 3 1

이 테스트 케이스가 오류 잡는데 중요한 단서가 되었다. ㅠㅠ

 

아이디어는

Step1. 상어의 현 위치에서 BFS로 먹을수있는 먹이감까지 최단거리를 구해준다

Step2. 조건에 따라 먹이의 우선순위는 위+좌측이니까 순서대로 탐색하면서 최소 거리를 갱신해준다.

Step3. 상어의 위치를 변경해주고 필요한 연산을 해준다.

Step4. 더이상 상어가 이동할 수 없을때까지 반복한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def simulation(y, x, weight):
    global n, answer
    queue = [(y, x, weight, weight)]
 
    while queue:
        curr_y, curr_x, curr_w, cnt = queue.pop(0)
 
        # BFS 로 상어의 현재위치에서 각 먹이감 까지 거리를 계산한 배열을 가져온다.
        dist_arr = bfs(curr_y, curr_x, curr_w)
        dist = 987654321
        for i in range(n):
            for j in range(n):
                if 0<MAP[i][j]<curr_w and MAP[i][j] != 9:
                    tmp = dist_arr[i][j] # BFS로 계산한 해당 좌표의 최소값을 임시로 할당
 
                    # 중요. tmp = -1 일 경우 tmp 최소값으로 -1이 잡혀서 틀림
                    if tmp < dist and tmp != -1:
                        next_y, next_x = i, j
                        dist = tmp
 
        if dist != 987654321:
            # 상어의 위치를 바꾼다.
            MAP[curr_y][curr_x] = 0
            MAP[next_y][next_x] = 9
            answer += dist # 거리를 더해줌
            cnt -= 1 # 무게 수만큼 물고기를 먹을 때 체중 증가해야하므로
 
            if cnt == 0# 0이 되는 순간
                curr_w += 1 # 현재 체중을 1 증가
                cnt = curr_w # 무게 수는 다시 현재 체중으로 초기화
 
            # # 상어 이동경로 출력
            # print("############")
            # for m in MAP:
            #     print(m)
            # print("dist {} cumul {} weight {}".format(dist, answer, curr_w))
            # print()
 
            queue.append((next_y, next_x, curr_w, cnt)) # 상어의 위치와 무게를 queue에 넣어서 시뮬레이션을 반복한다.
 
 
def bfs(st_y, st_x, weight): #상어의 현재위치에서 각 먹이감 까지 거리를 계산
    global n
    q = [(st_y, st_x)]
    check = [[-1]*for _ in range(n)]
    check[st_y][st_x] = 0
    while q:
        c_y, c_x = q.pop(0)
        for d in direction:
            n_y = c_y+d[0]
            n_x = c_x+d[1]
            if 0<=n_y<and 0<=n_x<n:
                if MAP[n_y][n_x] <= weight and check[n_y][n_x] == -1:
                    check[n_y][n_x] = check[c_y][c_x]+1
                    q.append((n_y, n_x))
    return check
 
direction = ((-10), (10), (0-1), (01))
= int(input())
MAP = [list(map(int, input().split())) for _ in range(n)]
answer = 0
 
flag = True
for i in range(n):
    for j in range(n):
        if MAP[i][j] == 9:
            simulation(i, j, 2)
            flag = False
            break
    if not flag:
        break
 
print(answer)
 
 
'''
#input
3
9 2 2
2 2 3
1 3 1
 
#output
2
 
 
#input
2
9 3
3 1
 
#output
0
'''
 
cs
728x90
반응형

'Problem Solving > BOJ' 카테고리의 다른 글

[Python]16939. 2x2x2 큐브  (0) 2019.04.10
[Python]16235. 나무 재테크  (0) 2019.04.10
[Python]6064. 카잉 달력  (0) 2019.04.09
[Python]17136. 색종이 붙이기  (0) 2019.04.08
[Python]1107. 리모컨  (0) 2019.04.08

댓글