본문 바로가기
Algorithm(BOJ, Python)/BFS&DFS

[백준_1245] 농장관리 python

by kurooru 2022. 9. 11.
# n, m 입력
n, m = map(int, input().split())

# farm 입력
farm = [
    list(map(int, input().split()))
    for _ in range(n)
]

# 함수들
# is_mount_top(x, y)
def is_mount_top(x, y):
    dxs, dys = [-1, -1, -1, 0, 0, 1, 1, 1], [-1, 0, 1, -1, 1, -1, 0, 1]
    for dx, dy in zip(dxs, dys):
        nx, ny = x + dx, y + dy
        # 주변 위치가 범위 내에 있으면서 현재 위치보다 높으면 실패
        if in_range(nx, ny) and farm[x][y] < farm[nx][ny]:
            return False
    # 그런 산봉우리가 없으면 성공
    return True

# in_range(x, y)
def in_range(x, y):
    return 0 <= x < n and 0 <= y < m

# can_spread(x, y)
def can_spread(x, y):
    # 범위 내에 있고, 방문한 적 없으면 가능
    return in_range(x, y) and not visited[x][y]

# bfs()
def bfs():

    # 전역 변수 선언
    global curr_x_y

    while q:
        x, y = q.popleft()
        # 주변 여덟개의 면 모두 확인해야 함
        dxs, dys = [-1, -1, -1, 0, 0, 1, 1, 1], [-1, 0, 1, -1, 1, -1, 0, 1]
        for dx, dy in zip(dxs, dys):
            nx, ny = x + dx, y + dy
            # 주변 위치로 퍼질 수 있으면,
            if can_spread(nx,ny) and farm[x][y] == farm[nx][ny]:
                # 큐에 넣어주고,
                q.append((nx, ny))
                # 방문 처리 해 주고
                visited[nx][ny] = 1
                # 후보 리스트에 올려주기
                curr_x_y.append((nx, ny))

# test(x, y)
def test(x, y):
    
    # 전역 변수 선언
    global curr_x_y
    
    # 현재 산봉우리의 좌표를 관리해 줄 리스트
    curr_x_y = []

    # 큐에 넣어주고,
    q.append((x, y))
    # 방문 처리 해 주고,
    visited[x][y] = 1
    # 산봉우리 후보 리스트에도 올려주고,
    curr_x_y.append((x, y))
    # bfs 호출
    bfs()

    # 현재 산봉우리에 대해,
    for curr_x, curr_y in curr_x_y:
        # 한번이라도 조건에 맞지 않는 산봉우리가 있다면,
        if not is_mount_top(curr_x, curr_y):
            # 실패
            return False
    
    # 모두 통과했다면 성공
    return True

# 설계
# 큐 사용준비
from collections import deque
q = deque()

# visited
visited =[
    [0] * m
    for _ in range(n)
]

# 산봉우리의 개수
mount_top = 0

# farm 을 돌면서
for i in range(n):
    for j in range(m):
        # 방문하지 않은 곳을 만나면,
        if not visited[i][j]:
            # bfs를 돌려주고,
            # 산봉우리인지 확인해주는 시험 실시
            if test(i, j):
                # 통과 시 산봉우리 갯수 추가
                mount_top += 1

# 출력
print(mount_top)