티스토리 뷰
(1) 깊이 우선 탐색 DFS
dfs : 깊이우선 탐색으로 넓게 퍼지며 탐색하는 것이 아니라 가장 깊은 곳까지 우선 탐색 후 넓게 퍼져가며 탐색하는 방법.
=> 깊이를 우선으로 먼저 탐색하고 탐색이 끝난 후에는 탐색을 시작한 위치로 돌아와 넓게 퍼지며 또 다른 노드에서 깊은 곳까지 탐색하는 방법.
=> 따라서, 중요한 것은 탐색한 지점을 기억해놔야한다는 점이고 이를 위해 재귀를 적절히 사용할 예정이다.
=> 익숙해지면 반복문을 통한 방법보다 재귀를 사용해 stack을 구현하는 것이 편리.
(2) 너비 우선 탐색 BFS
bfs : 너비 우선 탐색으로 넓게 퍼지며 현 위치 노드에 연결된 모든 노드를 우선으로 탐색하고 그 다음으로 한번 깊이를 들어가주며 그 노드의 연결된 모든 노드를 우선으로 탐색하는 방법
=> 한 노드에 연결된 모든 노드를 탐색하고 그 저장된 모든 노드들에 연결된 노드를 또 같은 방법으로 탐색하는 방법
=> bfs는 각 노드에 연결된 모든 노드를 queue에 저장하고 popleft()를 사용하며 먼저 저장한 것을 꺼내어 탐색해야하는 방법이기에 queue를 사용.
1. dfs와 bfs사용을 위한 스택, 큐, 재귀함수에 대한 기본 예제
#1. 스택 예제
stack =[]
stack.append(5)
stack.append(2)
stack.append(3)
stack.append(7)
stack.pop()
stack.append(1)
stack.append(4)
stack.pop()
print(stack)
#print(stack[::-1]) => 마지막에 넣은 것부터 출력할때 -> ::-1을 사용
#2. 큐 예제
from collections import deque
queue = deque()
queue.append(5)
queue.append(2)
queue.append(3)
queue.append(7)
queue.popleft()
queue.append(1)
queue.append(4)
queue.popleft()
print(list(queue))
#queue.reverse() => 역순으로 바꿔서 첫번째 원소부터 출력가능
#print(queue)
#3. 재귀함수 100번 호출하는 예제
def re_func(i):
if i==100:
return
else:
print(i)
return re_func(i+1)
re_func(0)
2. dfs와 bfs 개념잡기[+인접행렬, 인접리스트 구현방법]
#1.인접행렬
#인접행렬을 사용한 비용 및 연결성 나타내기
INF = 999999999
graph = [ [0,7.5],[7,0, INF],[5,INF, 0 ]]
print(graph)
#2.인접 리스트를 통한 그래프에 튜플로 (노드번호, 가중치) 넣기
#만약 노드가 3개면 3개의 행을 사용하고 열은 각 노드에 연결된 노드의 개수가 결정함. => memeory효율적
graph =[[] for _ in range(3)]
graph[0].append((1,7))
graph[0].append((2,5))
graph[1].append((0,7))
graph[2].append((0,5))
print(graph)
#3. stack과 재귀함수를 활용한 dfs예제풀기
graph = [[],[1,2,3,8],[1,2,7],[1,3,4,5],[3,4,5],[3,4,5],[6,7],[2,6,7,8],[1,7,8]]
stack=[]
visit=[0]*9
def re_func(i):
i = stack.pop()
visit[i]=1
print(i, end='')
for j in graph[i]:
if visit[j]!=1 and j!=i:
stack.append(j)
re_func(j)
stack.append(1)
visit[0]=1
re_func(1)
#4. bfs 알고리즘 : 너비우선 탐색
from collections import deque
queue= deque()
graph = [[],[1,2,3,8],[1,2,7],[1,3,4,5],[3,4,5],[3,4,5],[6,7],[2,6,7,8],[1,7,8]]
visit=[0]*9
visit[0]=1
visit[1]=1
queue.append(1)
for i in graph[1]:
if i!=1:
visit[i]=1
queue.append(i)
while(1):
i = queue.popleft()
print(i,end='')
for j in graph[i]:
if j!=i and visit[j]==0:
queue.append(j)
visit[j]=1
if len(queue)==0:
break
<기본 문제 풀어보기>
1. 하나의 지점에서 그 지점과 연결된 것들을 그룹화 시키는 문제
2. 하나의 지점에서 출발해 다른 지점으로 도달할때 몇번만에 갈 수 있는지 생각하는 문제
#1. 음료수 얼려 먹기 => 스택으로 들어가서 0이 연결된부분까지 계속 추적 -> 상하좌우로 계속
#얼음틀에 대한 list를 입력받는데 이때 1이 틀이고 0이 가능한 부분.
#최대몇개의 아이스크림이 나올 수 있는가?
n,m = map(int, input().split())
visit=[]
for i in range(0,n):
list_=[0]*m
visit.append(list_)
ice =[]
for h in range(0,n):
list_=list(map(int,input().split()))
ice.append(list_)
cnt=0
def dfs(i,j):
visit[i][j]=1
if i-1>=0 and (visit[i-1][j]==0 and ice[i-1][j]==0):
dfs(i-1,j)
if i+1<n and (visit[i+1][j]==0 and ice[i+1][j]==0):
dfs(i+1, j)
if j-1>=0 and (visit[i][j-1]==0 and ice[i][j-1]==0):
dfs(i,j-1)
if j+1<m and (visit[i][j+1]==0 and ice[i][j+1]==0):
dfs(i,j+1)
for i in range(0,n):
for j in range(0,m):
if ice[i][j]==0 and visit[i][j]==0:
visit[i][j]=1
dfs(i,j)
cnt+=1
print(cnt)
#2. 미로탈출 => 최단거리 => 큐사용하는 문제
# 최단거리는 갈 수 있는 모든 거리를 갈때 그 이전의 cnt를 기억해두고 상하좌우로 가며 cnt를 하나 증가시키는 문제
from collections import deque
queue_x = deque()
queue_y = deque()
queue_cnt = deque()
n,m= map(int, input().split())
map_list =[]
visit=[]
for i in range(0,n):
map_list.append(list(map(int,input())))
list_=[0]*m
visit.append(list_)
#동빈이는 항상 (0,0)에 존재한다고 설정하고 n-1,m-1이 항상 탈출구 위치임
cnt=0
def bsf():
while True:
x = queue_x.popleft()
y = queue_y.popleft()
cnt = queue_cnt.popleft()
#print(x,y,cnt)
if x==n-1 and y==m-1:
print(cnt)
return
if x-1>=0 and map_list[x-1][y]==1 and visit[x-1][y]!=1:
queue_x.append(x-1)
queue_y.append(y)
queue_cnt.append(cnt+1)
visit[x-1][y]=1
if x+1<n and map_list[x+1][y]==1 and visit[x+1][y]!=1:
queue_x.append(x+1)
queue_y.append(y)
queue_cnt.append(cnt+1)
visit[x+1][y]=1
if y-1>=0 and map_list[x][y-1]==1 and visit[x][y-1]!=1:
queue_x.append(x)
queue_y.append(y-1)
queue_cnt.append(cnt+1)
visit[x][y-1]=1
if y+1<m and map_list[x][y+1]==1 and visit[x][y+1]!=1:
queue_x.append(x)
queue_y.append(y+1)
queue_cnt.append(cnt+1)
visit[x][y+1]=1
queue_x.append(0)
queue_y.append(0)
queue_cnt.append(1)
visit[0][0]=1
bsf()
'파이썬 > 파이썬 기초' 카테고리의 다른 글
정렬 (0) | 2021.08.06 |
---|---|
구현 (0) | 2021.07.25 |
그리디 알고리즘 (0) | 2021.07.16 |
리스트를 다루는 map()과 filter() - lambda (0) | 2021.03.28 |
파이썬 기초 - 알아두면 유용 (0) | 2021.03.24 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 모듈 사용법
- 스택 파이썬
- 백준 11053 파이썬
- mm1queue
- DRF 회원관리
- LAMBDA
- c++덱
- 핀테크 트렌드
- 딥러닝입문
- 백트래킹(1)
- 4963 섬의개수
- 온라인프로필 만들기
- CSMA/CD란?
- 효율적인방법찾기
- 13886
- 백준 10866
- 기사작성 대외활동
- 소프트웨어공학설계
- 백준 4963
- 기본 텍스트 분류
- 10866 백준
- 파이썬 알아두면 유용
- stack 컨테이너
- 백준 숫자놀이
- 백준 15650 파이썬
- 영화 리뷰 긍정 부정 분류
- CREATE ASSERTION
- 코딩월드뉴스
- 11053 백준
- 시뮬레이션 c
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함