백준 1012: 유기농배추(실버2)

2024. 3. 31. 13:25·Algorithm(Python)

문제

차세대 영농인 한나는 강원도 고랭지에서 유기농 배추를 재배하기로 하였다. 농약을 쓰지 않고 배추를 재배하려면 배추를 해충으로부터 보호하는 것이 중요하기 때문에, 한나는 해충 방지에 효과적인 배추 흰 지렁이를 구입하기로 결심한다. 이 지렁이는 배추 근처에 서식하며 해충을 잡아먹음으로써 배추를 보호한다. 특히, 어떤 배추에 배추 흰 지렁이가 한 마리라도 살고 있으면 이 지렁이는 인접한 다른 배추로 이동할 수 있어, 그 배추들 역시 해충으로부터 보호받을 수 있다. 한 배추의 상하좌우 네 방향에 다른 배추가 위치한 경우에 서로 인접해 있는 것이다.

한나가 배추를 재배하는 땅은 고르지 못해서 배추를 군데군데 심어 놓았다. 배추들이 모여있는 곳에는 배추흰지렁이가 한 마리만 있으면 되므로 서로 인접해있는 배추들이 몇 군데에 퍼져있는지 조사하면 총 몇 마리의 지렁이가 필요한지 알 수 있다. 예를 들어 배추밭이 아래와 같이 구성되어 있으면 최소 5마리의 배추흰지렁이가 필요하다. 0은 배추가 심어져 있지 않은 땅이고, 1은 배추가 심어져 있는 땅을 나타낸다.

1 1 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
0 0 1 1 0 0 0 1 1 1
0 0 0 0 1 0 0 1 1 1

입력

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 첫째 줄에는 배추를 심은 배추밭의 가로길이 M(1 ≤ M ≤ 50)과 세로길이 N(1 ≤ N ≤ 50), 그리고 배추가 심어져 있는 위치의 개수 K(1 ≤ K ≤ 2500)이 주어진다. 그 다음 K줄에는 배추의 위치 X(0 ≤ X ≤ M-1), Y(0 ≤ Y ≤ N-1)가 주어진다. 두 배추의 위치가 같은 경우는 없다.

출력

각 테스트 케이스에 대해 필요한 최소의 배추흰지렁이 마리 수를 출력한다.

예제 입력 1 복사

2
10 8 17
0 0
1 0
1 1
4 2
4 3
4 5
2 4
3 4
7 4
8 4
9 4
7 5
8 5
9 5
7 6
8 6
9 6
10 10 1
5 5

예제 출력 1 복사

5
1

이문제도 가장 기본적인 그래프 문제였다.

 

문제를 풀기 위한 순서는 다음과 같이 정의했다.

 

순서

1. 밭(graph) 만들기

2. 테스트 케이스 갯수 받아오기

3. 밭에 배추 심어주기

4. 방문 그래프 만들기

5. 밭 안에서 심어져 있는 배추 위치 찾기 

6. (5)번 과정에서 배추가 찾아졌고, 아직 방문하지 않은 배추라면  지렁이 구입하고 bfs 실행

7. 총 지렁이 개수(?)

 

코드 블록

A. 위 순서중 (1), (2), (3) 

# 테스트 케이스 개수 입력
T = int(input())

for _ in range(T):
    # 가로길이 M, 세로길이 N, 배추 위치 개수 K 입력
    M, N, K = map(int, input().split())
    
    # 전체 배추 밭 초기화
    field = [[0] * M for _ in range(N)]
    visited = [[False] * M for _ in range(N)]
    
    # 배추 위치 입력
    for _ in range(K):
        y, x = map(int, input().split())
        field[x][y] = 1

이렇게 되면  (field) M x N의 밭과  전부 false로 적힌  (visited) M x N 밭이 만들어진다.

 

B. 배추가 있는 field 값에 visited값도 false 즉 아직 방문하지 않았다면 지렁이(count) 수를 하나 추가하고 bfs 실행

# 필요한 배추흰지렁이 수 초기화
    count = 0
    
    # 전체 배추 밭에 대해 탐색
    for i in range(N):
        for j in range(M):
            if field[i][j] == 1 and not visited[i][j]:
                bfs(i, j)
                count += 1
    print(count)

 

여기까지는 웬만한 그래프 문제와 거의 형식이 똑같다. 

A+B

# 테스트 케이스 개수 입력
T = int(input())

for _ in range(T):
    # 가로길이 M, 세로길이 N, 배추 위치 개수 K 입력
    M, N, K = map(int, input().split())
    
    # 전체 배추 밭 초기화
    field = [[0] * M for _ in range(N)]
    visited = [[False] * M for _ in range(N)]
    
    # 배추 위치 입력
    for _ in range(K):
        y, x = map(int, input().split())
        field[x][y] = 1
    
    # 필요한 배추흰지렁이 수 초기화
    count = 0
    
    # 전체 배추 밭에 대해 탐색
    for i in range(N):
        for j in range(M):
            if field[i][j] == 1 and not visited[i][j]:
                bfs(i, j)
                count += 1
    
    print(count)

 

C. 이제 여기서부터는 큐를 만들어서 B에서 고른 배추를 시작점으로 붙어있는 배추로 하나씩 옮겨주면 된다.

 

먼저 지렁이가 이동할 수 있는 경로는 상하좌우이다. 

# 상하좌우 이동을 위한 dx, dy 배열
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

 

다음은 본격적으로 bfs를 구현해 주면 된다.

 

def bfs(x, y):
    queue = deque()
    queue.append((x, y))
    visited[x][y] = True
    
    while queue:
        cx, cy = queue.popleft()
        for i in range(4):
            nx, ny = cx + dx[i], cy + dy[i]
            if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny] and field[nx][ny] == 1:
                visited[nx][ny] = True
                queue.append((nx, ny))

 

먼저 큐에 첫 배추가 들어와 주면, 방문 그래프에 방문을 했다 표기를 해준다.

 

다음으로는 큐에서 뺴주면서 그 근처에 붙어있는 배추가 있는지, 그리고 그 배추를 방문한 적이 없다면 마찬가지로

 

큐에 넣어준 다음 방문노드에 표사를 해준다. 

 

이런 식으로 진행을 한다면 결국 모든 배추를 돌 때까지 bfs가 실행을 하게 되는데 결론적으로 

 

구입해야 하는 지렁이 개수를 반환해 주게 된다. 

 


이문제에서 가장 중요한 포인트는 bfs를 한번 돌 때마다 count(지렁이 개수)를 하나씩 느려준다는 것이다.

 

문제에서 지렁이는 다른 인접한 배추로 움직일 수 있다 하였기에 붙어있는 배추 묶음이 몇 묶음인지 구해야 하기 때문이다.

 

아래는 전체 코드이다.

 

from collections import deque

# 상하좌우 이동을 위한 dx, dy 배열
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

def bfs(x, y):
    queue = deque()
    queue.append((x, y))
    visited[x][y] = True
    
    while queue:
        cx, cy = queue.popleft()
        for i in range(4):
            nx, ny = cx + dx[i], cy + dy[i]
            if 0 <= nx < N and 0 <= ny < M and not visited[nx][ny] and field[nx][ny] == 1:
                visited[nx][ny] = True
                queue.append((nx, ny))

# 테스트 케이스 개수 입력
T = int(input())

for _ in range(T):
    # 가로길이 M, 세로길이 N, 배추 위치 개수 K 입력
    M, N, K = map(int, input().split())
    
    # 전체 배추 밭 초기화
    field = [[0] * M for _ in range(N)]
    visited = [[False] * M for _ in range(N)]
    
    # 배추 위치 입력
    for _ in range(K):
        y, x = map(int, input().split())
        field[x][y] = 1
    
    # 필요한 배추흰지렁이 수 초기화
    count = 0
    
    # 전체 배추 밭에 대해 탐색
    for i in range(N):
        for j in range(M):
            if field[i][j] == 1 and not visited[i][j]:
                bfs(i, j)
                count += 1
    
    print(count)

'Algorithm(Python)' 카테고리의 다른 글

백준 2156: 포도주 시식(실버1)  (2) 2025.01.13
백준 2941: 크로아티아 알파벳(실버4)  (0) 2025.01.09
백준 14501: 퇴사(실버 3)  (2) 2024.06.04
백준 10026: 적록색약(골드 5)  (1) 2024.04.07
백준 14502: 연구소(골드 5)  (0) 2024.03.26
'Algorithm(Python)' 카테고리의 다른 글
  • 백준 2941: 크로아티아 알파벳(실버4)
  • 백준 14501: 퇴사(실버 3)
  • 백준 10026: 적록색약(골드 5)
  • 백준 14502: 연구소(골드 5)
무엇을해야하는지
무엇을해야하는지
어차피 잘될거지만, 그래도 꾸준히 열심히 최선을 다해서
  • 무엇을해야하는지
    What2Do
    무엇을해야하는지
  • 전체
    오늘
    어제
    • 분류 전체보기 (86)
      • MLOps (5)
        • DeepLearning(연구-논문) (0)
        • MS Azure AI (1)
        • MLOps projects (4)
      • DevOps&Cloud (21)
      • AWS (17)
      • Algorithm(Python) (25)
      • Springboot (8)
      • IT 시사 (2)
      • 운영체제 (4)
      • 네트워크 (2)
      • JAVA (1)
      • 면접&코테 후기 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    카엔프
    dp #dfs
    ec2 #instace
    leetcode #codesignal #코테 #그리디 #알고리즘
    SpringBoot
    백준
    cors #클라이언트 #서버 #서버사이드 렌더링
    BFS
    AWS
    3차원
    프로세스
    rockstat
    knapsack #가방 #백준 #dp #topdown
    dp #동적계획법 #백준 #파이썬
    스프링부트
    testcode #spring #단위테스트 #통합테스트
    tdd #테스트코드 #spring #springboot
    aws #iam #group #role
    EC2
    clpud
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
무엇을해야하는지
백준 1012: 유기농배추(실버2)
상단으로

티스토리툴바