N
: 땅의 가로 세로 크기 ()
L
, R
: 인구수 제한 ()
N
×N
크기의 땅은 1×1 크기의 칸으로 나누어져 있다.
각 땅엔 1개의 나라가 있고 그 나라가 (r,c)에 있을 때 인구는 A[r][c]
이다.
인접한 나라 사이엔 국경선이 있기 때문에 모든 국경선은 정사각형이다.
이 때, 조건에 따라 더 이상 인구 이동이 일어나지 않을 때까지 이동을 한다면 며칠이 걸리는지 구하는 문제이다.
인구 이동이 필요 없을 때까지 일어난다는 점에서 특정 조건까지 반복해야 하며, 인접 나라를 확인해야 하므로 BFS를 활용하고자 했다.
인접 나라는 상하좌우에 있기에 4가지 방향을 정의한다.
지나친 곳은 다시 방문하지 않으므로 방문한 곳을 저장해야 한다 → 방문 리스트 정의 필요!
BFS 탐색 조건은 다음과 같이 정의한다.
N
×N
범위 내인구 이동이 더 이상 필요 없을 때까지 이동을 반복해야 한다.
while문 내 이중 for문 →
BFS문 →
최종 시간복잡도
최악일 때 이 되는데 이는 제한시간 2초 내 충분히 수행 가능하다.
TypeError: unsupported operand type(s) for -: 'str' and 'str'
A = [list(input()) for _ in range(N)]
를 수정했다.import sys
from collections import deque
input = sys.stdin.readline
# bfs 구현
def bfs(x, y):
queue = deque([(x, y)])
# 연합 저장
union = [(x, y)]
while queue:
x, y = queue.popleft()
for i in range(4):
nx, ny = x + dx[i], y + dy[i]
# 범위 내 방문 여부 확인
if 0 <= nx < N and 0 <= ny < N and not visited[nx][ny]:
# 인구 차이 확인
if L <= abs(A[x][y] - A[nx][ny]) <= R:
visited[nx][ny] = 1
queue.append((nx, ny))
union.append((nx, ny))
return union
# 입력 받기
N, L, R = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(N)]
# 정답 초기화
answer = 0
# 인접 방향 확인
dx = [0, 0, -1, 1]
dy = [-1, 1, 0, 0]
# 인구 이동 필요 없을 때까지 반복
while True:
# 방문 리스트 정의
visited = [[0 for _ in range(N)] for _ in range(N)]
# 연합 유무 확인
union_flag = 0
# bfs 수행
for i in range(N):
for j in range(N):
if not visited[i][j]:
visited[i][j] = 1
union = bfs(i, j)
# 연합 있으면 인구수 분배
if len(union) > 1:
union_flag = 1
population = sum(A[x][y] for x, y in union) // len(union)
# 인구수 갱신
for x, y in union:
A[x][y] = population
# 연합 없으면 인구 이동 종료
if union_flag == 0:
print(answer)
break
# 아니면 날짜 추가 후 계속 반복
answer += 1