문제
https://www.acmicpc.net/problem/16234
https://www.acmicpc.net/problem/16234
정답
from collections import deque
n,l,r = map(int,input().split())
graph =[]
for _ in range(n):
graph.append(list(map(int,input().split())))
dx = [1,0,1,0]
dy = [0,-1,0,1]
def process(x,y,index): # 한 연합의 인구이동 로직
united = [] # 한 연합에 포함되는 나라가 담길 배열. 인구이동 시 필요
united.append((x,y))
q = deque() # dfs수행. 국경선을 여는 조건에 따라 연합을 확장시키기 위해 사용
q.append((x,y))
union[x][y] = index # 각 연합을 구분할 인덱스 번호 부여
summary = graph[x][y]
count = 1 # 한 연합에 속할 나라 개수
while q: # 연합이가능한 모든 나라를 연합시키는 작업
x,y = q.popleft()
for i in range(4):
nx = x+dx[i]
ny = y+dy[i]
if 0 <= nx < n and 0 <= ny < n and union[nx][ny] == -1:
if l <= abs(graph[nx][ny]-graph[x][y]) <= r:
q.append((nx,ny))
union[nx][ny] = index
summary += graph[nx][ny]
count +=1
united.append((nx,ny))
for i,j in united: # 연합이 끝난 후 인구이동.
graph[i][j] = summary//count
return count # 인구이동 발생했는지를 체크하기 위한 변수를 return
total_count = 0
while True:
move = False
union = [[-1]*n for _ in range(n)] # 전역변수처럼 process함수 안에서 사용이 가능
index = 0 # 다른 연합들과 구분되는 연합 번호를 매기는 것. 한 번의 이동이 끝나면 초기화됨
for i in range(n):
for j in range(n): # 전체 나라를 돌아가며 인구이동.
if union[i][j] == -1: # 만약 한 연합의 이동이 끝나고 연합이 된 나라를 다시 이동시키지 않도록 검사
if process(i,j,index) > 1:
move = True
index +=1 # 한 연합의 인구이동이 끝났다면 index를 증가시켜 다른 연합을 만듦
if move == False: # 인구이동이 일어나지 않았다면 프로세스 종료
break
total_count+=1 # 인구이동이 총 몇 번 일어났는지를 체크하는 변수
print(total_count)
풀이
코드에 주석을 달아서 설명했음.
인구이동이 일어나지 않았을 때를 어떻게 뭘로 판단하느냐가 제일 어려웠던 것 같다.
본문처럼 move변수를 이용해 인구이동 함수 process()를 실행한 후 리턴값으로 각 연합에 속한 나라 수를 설정하는 방법은 쉬웠는데 정답지에는 index == n*n이 될 때 전체 프로그램을 종료시키는 것으로 구현했다.
이 index가 n*n이 되는게 대체 무슨 말인지 이해를 못해서 한참을 고민했는데 결국 알아내지 못함..
hoxy... ㅇㅏ는사람이 있다면 알려주길..
참고
이것이 취업을 위한 코딩테스트다(with.python)
'코딩테스트 > 👩💻 이코테' 카테고리의 다른 글
[이코테/이진탐색/백준] 공유기 설치(정답,풀이) (0) | 2023.10.18 |
---|---|
[이코테/정렬] 카드 정렬하기 (0) | 2023.10.18 |
[이코테/dfs/백준] 감시 피하기(정답,풀이) (0) | 2023.10.15 |
[이코테/dfs/삼성기출] 연산자 끼워넣기(정답,해설) (0) | 2023.10.15 |
[이코테/구현/카카오 기출] 외벽 점검 (정답, 풀이) (1) | 2023.10.13 |