728x90
https://www.acmicpc.net/problem/16234
16234번: 인구 이동
N×N크기의 땅이 있고, 땅은 1×1개의 칸으로 나누어져 있다. 각각의 땅에는 나라가 하나씩 존재하며, r행 c열에 있는 나라에는 A[r][c]명이 살고 있다. 인접한 나라 사이에는 국경선이 존재한다. 모
www.acmicpc.net
접근법
- 각 나라를 돌면서 인접한 나라와의 인구 차를 계산하고, L이상 R이하라면 union_country에 추가 -> bfs 활용
- union_country에 있는 국가들로 인구수를 업데이트 함.
- 더 이상 인구이동이 없을 때까지 반복 -> flag변수를 활용
from collections import deque
def init_func(N):
arr = []
for i in range(N):
arr.append(list(map(int, input().split())))
return arr
def bfs(x, y, L, R):
"""
:param x: 현재 위치 x
:param y: 현재 위치 y
:param L, R: L 이상 R이하의 인구수 차이라면 Union
:return:
"""
# 인접한 나라의 위치
d = [(1,0), (0,1), (-1, 0), (0,-1)]
q = deque()
N = len(arr)
union_country = []
# 현재 위치를 q와 union_country에 추가
q.append((x,y))
union_country.append((x,y))
while q:
x,y = q.popleft()
for move_x, move_y in d:
nx = x + move_x
ny = y + move_y
if (0 <= nx < N) and (0 <= ny < N) and not (visited[nx][ny]):
if L <= abs(arr[x][y] - arr[nx][ny]) <= R:
visited[nx][ny] = True
q.append((nx,ny))
union_country.append((nx,ny))
return union_country
def solution(N, L, R):
answer = 0
while True:
global visited
visited = [[0]*N for _ in range(N)]
move = False
for i in range(N):
for j in range(N):
if not visited[i][j]:
visited[i][j] = True
union_country = bfs(i, j, L, R)
if 1 < len(union_country):
move = True
population = sum([arr[x][y] for x, y in union_country]) // len(union_country)
for x, y in union_country:
arr[x][y] = population
# 인구 이동이 일어나지 않은 경우
if not move:
break
# 인구이동이 일어난 경우
else:
answer += 1
print(answer)
def main():
N, L, R = map(int, input().split())
global arr
arr = init_func(N)
solution(N, L, R)
if __name__=="__main__":
main()
처음 생각했던 알고리즘의 문제점(틀린이유)
더보기
try1
(1) find_neighbor함수에서 candidate_list에 모든 후보 리스트를 넣지 않은듯.
from collections import deque
def find_neighbor(map_arr, cur, min, max, visited):
neighbor_list = []
neighbor_total = 0
while cur:
cur_x, cur_y = cur.popleft()
candidate_list = [[cur_x+1, cur_y], [cur_x,cur_y+1]]
for can_x, can_y in candidate_list:
if (can_x >= len(map_arr)) or (can_y >= len(map_arr)):
continue
if visited[can_x][can_y] == 1:
continue
diff = abs(map_arr[cur_x][cur_y] - map_arr[can_x][can_y])
if (diff >= min) and (diff <= max):
visited[can_x][can_y] = 1
neighbor_list.append([can_x, can_y])
neighbor_total += map_arr[can_x][can_y]
cur.append([can_x, can_y])
return neighbor_list, neighbor_total
def count_days(map_arr,L, R):
# 재귀로 연결된 모든 이웃들을 찾아야 함.
day = 0
# while(True):
visited = [[0 for j in range(len(map_arr))] for i in range(len(map_arr))]
nation_list = deque()
nation_list.append([0,0])
visited[0][0] = 1
while(nation_list):
for i in range(len(map_arr)):
for j in range(len(map_arr)):
neighbor, neighbor_total = find_neighbor(map_arr, nation_list, L, R, visited)
neighbor.append([i,j])
# print("current : ", (i, j), "neighbor : ", neighbor)
for nation_x, nation_y in neighbor:
map_arr[nation_x][nation_y] = neighbor_total/len(neighbor)
day += 1
return day
def input_arr(N):
arr = []
for i in range(N):
arr_tmp = list((map(int, input().split())))
arr.append(arr_tmp)
return arr
def main():
N, L, R = map(int, input().split())
map_arr = input_arr(N)
result = count_days(map_arr, L, R)
print(result)
if __name__ == "__main__":
main()
사용된 알고리즘
구현, 그래프 이론, 그래프 탐색, 너비 우선 탐색, 시뮬레이션
728x90
'study > 백준(BOJ)' 카테고리의 다른 글
[Python] 1463. 1로 만들기 (0) | 2023.05.12 |
---|---|
[Python] 17626. Four Squares (0) | 2023.05.12 |
[Python] 2110. 공유기 설치 (0) | 2023.04.27 |
[Python] 7795. 먹을 것인가 먹힐 것인가 (0) | 2023.04.27 |
[Python] 27211. 도넛 행성 (0) | 2023.04.25 |