일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- DART
- 개발
- Vue
- vuejs
- 안드로이드
- django
- Python
- Algorithm
- 코테
- 파이썬
- 안드로이드스튜디오
- C++
- 동적계획법
- 알고리즘
- DFS와BFS
- 동적계획법과최단거리역추적
- 백준
- 코딩테스트
- 분할정복
- DFS
- cos
- cos pro
- issue
- Flutter
- AndroidStudio
- codingtest
- android
- BAEKJOON
- cos pro 1급
- 코드품앗이
- Today
- Total
Development Artist
[Baekjoon, Python] 1012번 : 유기농 배추 본문
도입
백준 단계별 풀기 DFS와 BFS 네 번째 문제이다.
DFS와 BFS
DFS
- Root Node 혹은 다른 임의의 Node에서 이어진 Branch를 완벽하게 탐색하고 다른 이어진 Branch로 넘어가는 방법.
한 방향으로 계속 가서 끝을 마주하면 다른 방향으로 설정해서 마찬가지로 진행.
- Stack 또는 Recursive함수로 구현.
- 시간 복잡도 : 인접 리스트는 $O(V+E)$ 인접 행렬은 $O(V^2)$ // 접점(V), 간선(E)
BFS
- Root Node 혹은 다른 임의의 Node에서 이어진 Branch들의 바로 하나 건너 있는 Node들을 먼저 탐색.
- Queue로 구현
- 시간 복잡도 : 인접 리스트는 $O(V+E)$ 인접 행렬은 $O(V^2)$ // 접점(V), 간선(E)
풀이
1. 이전의 단지번호붙이기 문제와 같이 좌표를 활용하는 문제이다. 2차원 배열(fied)의 인덱스 값을 좌표로 사용한다. 또한, dx, dy로 상, 하, 좌, 우를 확인하고자 한다.
2. dfs로 인접한 배추들(노드들)을 하나의 배추흰지렁이(var_cnt)로 계산한다. dfs를 호출한다는 것은, 인접한 배추로 가는 것을 의미하는데, 그렇다면 배추흰지렁이(var_cnt)를 어디서 카운팅하는지를 고민해 봐야한다. 어렵지 않다. field[i][j] = 1일때 bfs를 콜을 하고 dfs를 끝내고 서브루틴이 전부 끝난 부분에서 var_cnt += 1을 해준다.
3. dfs 함수 시작부분에서, field[x][y] 에 0의 값을 넣는다. 방문한 곳은 방문했다고 0값을 넣어줘서 재방문을 방지하기 위함이다.
4. 문제를 풀다가 RecursionError를 만나서 확인해보았다. BOJ 사이트에서는 가장 많이 발생하는 이유로 'Python이 정한 최대 재귀 깊이보다 재귀의 깊이가 더 깊어질 때'라고 설명하고 있다. 1000으로 제한하고 있는데, sys.setrecursionlimit(10000)으로 제한의 정도를 10배 더 주었더니, 해결이 되었다. 파이썬으로 재귀함수를 쓸 때, 특히 DFS, BFS에서는 필수적인 코드라고 설명을 하고 있다.
5. 2차원 배열의 선언에서 2중 for문, 1 연산자와 1 for문, 2 연산자 방법이 있다. 틀렸습니다가 나오길래...로직에서 문제를 도저히 찾지 못했다. field의 선언 문제인가 싶어서 처음에 진행했던 2연산자 방법( [[0]*var_x]*var_y )에서 1연산자 1 for문( [[0]*var_x for _ in range(var_y)] )으로 하니까 되었다....
코드
import sys
from sys import stdin
sys.setrecursionlimit(10000)
dx=[-1,0,1,0] # 좌 우
dy=[0,1,0,-1] # 상 하
def dfs(x,y):
field[x][y] = 0 # 방문한 배추는 0
for i in range(4):
nx = x + dx[i] #i=0 좌 , i=1 상, i=2 우 , i=3 하
ny = y + dy[i]
if (0 <= nx < var_y) and (0 <= ny < var_x):
if field[nx][ny] == 1:
dfs(nx, ny)
var_test_case = int(stdin.readline())
for _ in range(var_test_case):
# 가로길이, 세로길이, 배추 개수
var_x, var_y, var_cabbage = map(int, stdin.readline().split())
# field = [[0]*var_x]*var_y # 2중 연산자로 2차원 배열 초기화 (틀렸습니다)
field = [[0]*var_x for _ in range(var_y)]
var_cnt = 0
# 배추 심기
for _ in range(var_cabbage):
ty,tx = map(int, stdin.readline().split())
field[tx][ty] = 1
# 벌레 수 정하기
for i in range(var_y):
for j in range(var_x):
if field[i][j] > 0 :
dfs(i,j)
var_cnt += 1
print(var_cnt)
마무리
*^^*
'Algorithm > Baekjoon' 카테고리의 다른 글
[Baekjoon, Python] 7576번 : 토마토 (0) | 2021.03.09 |
---|---|
[Baekjoon, Python] 2178번 : 미로 탐색 (0) | 2021.03.07 |
[Beakjoon, Python] 2667번 : 단지번호붙이기 (0) | 2021.03.04 |
[Baekjoon, Python] 2606번 : 바이러스 (0) | 2021.03.03 |
[Baekjoon, Python] 1260번 : DFS와 BFS (0) | 2021.03.02 |