https://www.acmicpc.net/problem/16234
PyPy3로 통과
from collections import deque
import sys
input = sys.stdin.readline
""" 입력 """
N, L, R = map(int, input().split())
country = [list(map(int, input().split())) for _ in range(N)]
def solve():
ans = 0
while True:
"""
(r1, c1), (r2, c2)가 국경선을 공유할 수 있다면
border[r1][c1] == border[r2][c2], 같은 코드를 가짐
"""
border = [[0]*N for _ in range(N)]
code = 1
for r in range(N):
for c in range(N):
if border[r][c] == 0:
bfs(r, c, border, code)
code += 1
""" bfs 수행 후 border 출력하는 코드
print("bfs 이후 border 상태")
for border_row in border:
print(border_row)
"""
"""
union_info
union_info[code] = [(r1, c1), (r2, c2), ...]
같은 code를 공유하는 연합국들의 좌표를 저장한다
"""
union_info = [[] for _ in range(code)]
for r in range(N):
for c in range(N):
if border[r][c] != 0:
union_info[border[r][c]].append((r, c))
""" union_info 출력하는 코드
print("union_info")
for union_info_row in union_info:
print(union_info_row)
"""
# 인구 이동 시키기
stop = True
for i in range(1, code):
# 한 국가만 있는 연합은 연합이 아니다
if len(union_info[i]) <= 1:
continue
else:
stop = False # 연합이 하나라도 존재하면 stop 하지 않는다
union_count = len(union_info[i]) # 연합을 이루는 칸의 개수
union_people = 0 # 연합의 인구 수
for x in union_info[i]:
union_people += country[x[0]][x[1]]
union_people = union_people // union_count # 인구 수
# 인구를 이동시킨다
for x in union_info[i]:
country[x[0]][x[1]] = union_people
if stop:
return ans # 더이상 이동 없음. loop 종료, 함수 반환
else:
ans += 1 # 날짜 카운트 증가
return ans
def bfs(r, c, border, code):
q = deque([(r, c)])
border[r][c] = code
moves = [(0, 1), (0, -1), (1, 0), (-1, 0)]
while q:
r, c = q.popleft()
for move in moves:
new_r = r + move[0]
new_c = c + move[1]
if 0 <= new_r < N and 0 <= new_c < N:
if border[new_r][new_c] == 0:
# 인구 차이
diff = abs(country[r][c] - country[new_r][new_c])
if L <= diff <= R:
# 국경선을 공유
border[new_r][new_c] = border[r][c]
q.append((new_r, new_c))
print(solve())
이를 border라는 리스트에 나타낸다.
(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 1)에 위치한 국가들이 국경을 공유한다. 인구 이동.(1, 2), (2, 1), (2, 2)에 위치한 국가들이 국경을 공유한다. 인구 이동.(한 국가만으로 이루어진 연합은 국경을 공유하는 것으로 보지 않는다) 인구 이동은 발생하지 않는다. 루프 중단.(연합의 인구수) / (연합을 이루고 있는 칸의 개수)를 구하거나, 인구 이동 후 인구수를 업데이트 해줄 때 좀 더 빠르고 편리하게 접근하기 위해서 union_info에 같은 연합인 나라들의 좌표를 저장해둔다.
한 국가만으로 이루어진 연합은 국경을 공유하는 것으로 보지 않는다!stop을 이용하여 loop를 빠져나온다.