블로그 이사🏡 했습니다. 👉🏻 둘러보기
본문 바로가기
  • What Get's You Here, Won't Get You There
CS/Problem-solving

백준 1743번 파이썬

by OMIN_ 2022. 5. 5.

문제 링크

https://www.acmicpc.net/problem/1743

 

1743번: 음식물 피하기

첫째 줄에 통로의 세로 길이 N(1 ≤ N ≤ 100)과 가로 길이 M(1 ≤ M ≤ 100) 그리고 음식물 쓰레기의 개수 K(1 ≤ K ≤ N×M)이 주어진다.  그리고 다음 K개의 줄에 음식물이 떨어진 좌표 (r, c)가 주어진다

www.acmicpc.net

 

시간 제한 / 메모리 제한

2 초 128 MB

 

문제

코레스코 콘도미니엄 8층은 학생들이 3끼의 식사를 해결하는 공간이다. 그러나 몇몇 비양심적인 학생들의 만행으로 음식물이 통로 중간 중간에 떨어져 있다. 이러한 음식물들은 근처에 있는 것끼리 뭉치게 돼서 큰 음식물 쓰레기가 된다.

이 문제를 출제한 선생님은 개인적으로 이러한 음식물을 실내화에 묻히는 것을 정말 진정으로 싫어한다. 참고로 우리가 구해야 할 답은 이 문제를 낸 조교를 맞추는 것이 아니다. 

통로에 떨어진 음식물을 피해가기란 쉬운 일이 아니다. 따라서 선생님은 떨어진 음식물 중에 제일 큰 음식물만은 피해 가려고 한다. 

선생님을 도와 제일 큰 음식물의 크기를 구해서 “10ra"를 외치지 않게 도와주자.

 

입력

첫째 줄에 통로의 세로 길이 N(1 ≤ N ≤ 100)과 가로 길이 M(1 ≤ M ≤ 100) 그리고 음식물 쓰레기의 개수 K(1 ≤ K ≤ N×M)이 주어진다.  그리고 다음 K개의 줄에 음식물이 떨어진 좌표 (r, c)가 주어진다.

좌표 (r, c)의 r은 위에서부터, c는 왼쪽에서부터가 기준이다. 입력으로 주어지는 좌표는 중복되지 않는다.

출력

첫째 줄에 음식물 중 가장 큰 음식물의 크기를 출력하라.

예제 입력

3 4 5
3 2
2 2
3 1
2 3
1 1

예제 출력

4

힌트

# . . .
. # # .
# # . .

위와 같이 음식물이 떨어져있고 제일큰 음식물의 크기는 4가 된다. (인접한 것은 붙어서 크게 된다고 나와 있음. 대각선으로는 음식물 끼리 붙을수 없고 상하좌우로만 붙을수 있다.)

 

문제 풀이를 위해 생각한 것

  1. 최대 100*100의 지도에서 방문처리를 안 하면, 1억 번 이상의 연산이 수행될 것이고, 시간초과가 될 것이다.
  2. 최대 10,000개의 음식물이 입력으로 주어진다. 빠른 입력을 활용해야 한다.
  3. 음식물 입력을 받으면, N*M의 지도에 음식물을 표시한다.
  4. 2차원 배열의 [0][0] 부터 [n-1][m-1]까지 음식물 여부와 방문 여부를 고려하여 DFS로 해당 인덱스와 인접한 음식물을 모두 탐색하고, 그 크기를 리턴한다.
  5. 이때 방문한 지점은 방문처리 해서 연산낭비를 최소화한다.
  6. DFS의 리턴 값을 전역변수 cnt와 비교하여, 더 큰 값을 cnt에 저장한다.

 

 

사용한 자료구조 / 알고리즘

2차원 배열 / DFS(재귀)

 

풀이 코드

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)

n, m, k = map(int, input().split())
board = [[0 for _ in range(m)] for _ in range(n)]
visited = [[False for _ in range(m)] for _ in range(n)]
dx = (1, -1, 0, 0)
dy = (0, 0, 1, -1)
cnt = 0

for _ in range(k):
    r, c = map(int, input().split())
    board[r-1][c-1] = 1


def dfs(x, y):

    visited[x][y] = True
    _cnt = 1

    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]

        if 0 <= nx < n and 0 <= ny < m and board[nx][ny] == 1 and not visited[nx][ny]:
            _cnt += dfs(nx, ny)

    return _cnt


for i in range(n):
    for j in range(m):
        if not visited[i][j] and board[i][j] == 1:
            cnt = max(cnt, dfs(i, j))

print(cnt)

 

시간 복잡도 분석

O(N^2).

모든 지점을 탐색하여, 음식물 여부를 확인해야 한다. 최악의 경우 N = M으로, 시간복잡도는 O(N^2)이다.

 

문제에서 중요한 부분

전역변수 cnt와, 지역변수 _cnt를 구분해야 한다.

한 번 DFS를 해서 도출한 음식물의 수 중 최댓값이 이 문제에서 요구하는 답이다.

'CS > Problem-solving' 카테고리의 다른 글

백준 2583번 파이썬  (0) 2022.05.05
백준 2667번 파이썬  (0) 2022.05.05
백준 1182번 파이썬  (0) 2022.05.05
백준 2178번 파이썬  (0) 2022.05.02
백준 11724번 파이썬  (0) 2022.05.02

댓글