diff --git "a/week15/BOJ_1012/\354\234\240\352\270\260\353\206\215 \353\260\260\354\266\224_\352\271\200\354\204\240\354\247\204.py" "b/week15/BOJ_1012/\354\234\240\352\270\260\353\206\215 \353\260\260\354\266\224_\352\271\200\354\204\240\354\247\204.py" new file mode 100644 index 0000000..6d4b2b3 --- /dev/null +++ "b/week15/BOJ_1012/\354\234\240\352\270\260\353\206\215 \353\260\260\354\266\224_\352\271\200\354\204\240\354\247\204.py" @@ -0,0 +1,92 @@ +""" +Input: T(테스트 케이스의 개수) / M(배추밭의 가로 길이), N(배추밭의 세로 길이), K(배추가 심어져있는 위치의 개수) / X, Y(배추의 위치) +Output: 각 테스트 케이스에 대해 필요한 최소의 배추흰지렁이 마리 수 +Constraints: +- 1 <= M <= 50 / 1 <= N <= 50 / 1 <= K <= 2500 / 0 <= X <= M - 1 / 0 <= Y <= N - 1 +- 두 배추의 위치가 같은 경우는 없다. + +문제 설명 +어떤 배추에 배추흰지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다. -> 한 배추의 상하좌우 네 방향에 다른 배추가 위치한 경우에 서로 인접해있는 것이다. + +문제 풀이 +1이 인접한 칸들을 연결하여 한 구역이라고 생각하면, 구역마다 지렁이 1마리가 필요하다고 생각할 수 있다. +그래서 처음에 그래프의 각 칸을 돌다가 1인 칸을 발견하면 BFS를 수행한다. +BFS를 수행하면 1인 칸은 0으로 변경하게 되므로, 한 구역의 BFS가 모두 끝나면 그 구역은 1이 모두 0으로 바뀐다. +즉, 1인 칸 하나를 발견하여 그 칸에서 BFS를 수행하면 그 구역의 1은 모두 0으로 바뀌므로, 1인 칸을 발견할 때마다 카운트 + 1을 하고 BFS를 수행하면 정답을 구할 수 있다. + +주의 +- 배추흰지렁이는 계속해서 인접한 1로 이동할 수 있다. +- 가로 길이 M, 세로 길이 N + +시간 복잡도 -> O(M * N) * O(배추의 개수) +BFS를 사용하므로 모든 정점을 한 번씩 방문하고, 각 정점에서 상하좌우로 이동할 때 상수시간이 걸린다. -> O(V + E) (V: 정점의 수, E: 간선의 수) +각 테스트 케이스마다 M * N개의 위치를 모두 확인하고, BFS를 통해 연결된 배추 영역을 찾으므로 시간 복잡도는 대략 O(M * N)이다. 하지만 각 위치에서 BFS를 수행할 때 모든 배추를 방문하므로 실제로는 O(M * N) * O(배추의 개수)? + +공간 복잡도 -> O(M * N) +큐의 크기는 최악의 경우 모든 위치를 포함할 수 있다. -> O(M * N) +matrix에 대한 공간 -> O(M * N) +""" +import sys +from collections import deque + +input = sys.stdin.readline + +T = int(input()) #테스트케이스의 개수 + +# 이동 방향을 나타내는 리스트 +dx = [-1,1,0,0] # x좌표의 이동 방향에 대한 리스트 = [하, 상, 0, 0] +dy = [0,0,-1,1] # y좌표의 이동 방향에 대한 리스트 = [0, 0, 우, 좌] + +def BFS(x,y): + queue = [(x,y)] # 시작 위치 (x, y)를 받아와서 그 위치를 큐에 추가한다. + matrix[x][y] = 0 # 해당 위치의 값을 0으로 바꾸어 방문한 것으로 표시한다. + + while queue: # 큐가 비어있을 때까지 반복문을 실행한다. + x, y = queue.pop(0) # 큐에서 하나의 위치를 꺼낸다. + + for i in range(4): # 현재 위치에서 상, 하, 좌, 우 방향으로 이동하면서 유효한 위치인지 확인한다. + nx = x + dx[i] + ny = y + dy[i] + + if nx < 0 or nx >= M or ny < 0 or ny >= N: + continue + + if matrix[nx][ny] == 1 : # 만약 새로운 위치가 1로 표시된 배추가 심어져있는 위치이면, 해당 위치를 큐에 추가하고 값을 0으로 바꿔서 방문한 것으로 표시한다. + queue.append((nx,ny)) + matrix[nx][ny] = 0 + +# 행렬만들기 +for i in range(T): + M, N, K = map(int,input().split()) + matrix = [[0]*(N) for _ in range(M)] + """ + [ + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0], + [0, 0, 0] + ] + """ + cnt = 0 + + for j in range(K): + x,y = map(int, input().split()) + matrix[x][y] = 1 + """ + [ + [0, 0, 1], + [0, 0, 1], + [0, 0, 1], + [0, 0, 1], + [1, 0, 1] + ] + """ + + for a in range(M): + for b in range(N): + if matrix[a][b] == 1: + BFS(a,b) + cnt += 1 + + print(cnt) \ No newline at end of file