- 문제 : https://www.acmicpc.net/problem/16234

 

문제 이해 

- 특정 지점을 중심으로 bfs 탐색을 하면서 조건에 만족하는 노드를 모은 다음 전체의 평균으로 값을 업데이트하는 문제다.

- bfs 로직은 그렇게 어렵지 않았는데, 헷갈렸던 부분이 어떤 부분으로 bfs를 시작할지였다. while문에 이중 for문을 사용해야할 것 같은데 문제보니까 같은 지점도 중복으로 인구이동을 하는 것 같은데 이거를 어떻게 해야할지 몰랐다.

- 그래서 풀이를 보니까 while문을 시작할 때 visit를 초기화해서 방문하지 않은 지점을 중심으로 bfs를 하고, bfs 하면서 조건을 만족했던 지점들을 배열로 문제를 해결했다. 

- 반환한 배열(result)을 조건에 따라 인구이동을 하면 된다.

 

풀이 로직 

- n, l, r 과 matrix를 입력값으로 받는다. 

- while문을 돌면서 visit를 새로 설정하고 이중 for문을 돌면서 방문하지 않은 지점들을 중심으로 bfs를 진행한다. bfs를 통해 인구이동을 할 수 있는 노드들의 위치를 result로 가져온다. 이때 인구이동을 하므로 flag = True로 설정한다.

- result의 원소 개수가 2개 이상이라면 인구 이동을 할 수 있으므로 인구이동을 한다. 

인구 이동 로직은 다음과 같다. 각 지점의 matrix 값을 모두 더한 다음에 전체 개수를 나눠서 각 result 지점에 덮어씌워주면 된다. 

# 인구 이동을 할 수 있을 때
if len(result) >= 2:
	flag = True
	total = 0
	for i, j in result:
		total += matrix[i][j]
		temp = total // len(result)
	for i, j in result:
		matrix[i][j] = temp

- 더이상 인구 이동을 하지 않으면 이중 for문을 나왔을 때 flag == False 이므로 그때 while문을 나와주고, 아니라면 다시 처음부터 시작한다.

 

정답 풀이 

- bfs

def bfs(x, y, matrix, visit):
    visit[x][y] = 1
    result = [[x, y]]
    queue = [[x, y]]
    while queue:
        x, y = queue.pop(0)
        for i in range(4):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < n:
                if not visit[nx][ny] and l <= abs(matrix[nx][ny] - matrix[x][y]) <= r:
                    visit[nx][ny] = 1
                    queue.append([nx, ny])
                    result.append([nx, ny]) 
    return result

 

- 인구 이동

# 인구 이동을 할 수 있을 때
if len(result) >= 2:
	flag = True
	total = 0
	for i, j in result:
		total += matrix[i][j]
		temp = total // len(result)
	for i, j in result:
		matrix[i][j] = temp

 

- 전체 코드

def bfs(x, y, matrix, visit):
    visit[x][y] = 1
    result = [[x, y]]
    queue = [[x, y]]
    while queue:
        x, y = queue.pop(0)
        for i in range(4):
            nx, ny = x + dx[i], y + dy[i]
            if 0 <= nx < n and 0 <= ny < n:
                if not visit[nx][ny] and l <= abs(matrix[nx][ny] - matrix[x][y]) <= r:
                    visit[nx][ny] = 1
                    queue.append([nx, ny])
                    result.append([nx, ny]) 
    return result
    
n, l, r = map(int, input().split())
matrix = []
dx, dy = [-1, 1, 0, 0], [0, 0, -1, 1]
for _ in range(n):
    matrix.append(list(map(int, input().split())))
    
answer = 0
while True:
    flag = False
    visit = [[0] * n for _ in range(n)]
    for x in range(n):
        for y in range(n):
            if not visit[x][y]:
                result = bfs(x, y, matrix, visit)
                # 인구 이동을 할 수 있을 때
                if len(result) >= 2:
                    flag = True
                    total = 0
                    for i, j in result:
                        total += matrix[i][j]
                    temp = total // len(result)
                    for i, j in result:
                        matrix[i][j] = temp
                                       
    if flag == False:
        break
        
    answer += 1
        
print(answer)

'백준 > Search' 카테고리의 다른 글

[bfs/백준] 5427번 : 불  (0) 2023.05.22
[bfs/백준] 2206번 : 벽 부수고 이동하기  (0) 2023.05.20
[bfs/백준] 7576번 : 토마토  (0) 2023.05.17
[bfs/백준] 6593번 : 상범 빌딩  (0) 2023.05.16
[bfs/백준] 5014번 : 스타트링크  (0) 2023.05.16

+ Recent posts