본 내용은 해당 강의 토대로 작성
1. 미로탐색(DFS)
문제 해설
- 방법의 수를 구하는 것에 유의 -> DFS
- 지나온 길은 재방문하지 않는다.
- 경로를 탐색 후 지나온 길의 체크를 풀 것
문제 답안
dx = [-1, 0, 1, 0]; # 방향
dy = [0, 1, 0, -1];
def DFS(x, y):
global cnt;
if x == 6 and y == 6: # 도착지점
cnt += 1;
else:
for i in range(4):
xx = x + dx[i]; # 갈 곳
yy = y + dy[i];
if 0 <= xx <= 6 and 0 <= yy <= 6 and board[xx][yy] == 0:
board[xx][yy] = 1; # 체크
DFS(xx, yy);
board[xx][yy] = 0; # 체크 풀기
if __name__ == "__main__":
board = [list(map(int, input().split())) for _ in range(7)];
cnt = 0;
board[0][0] = 1; # 출발점 체크
DFS(0, 0);
print(cnt);
2. 등산경로(DFS)
문제 해설
- 출발점, 도착점이 입력에 따라 달라진다.
- 이동 시, 자신보다 높은 값으로만 이동이 가능하다.
- 이동 경로를 체크하며 탐색
- 되돌아오면, 체크를 풀기
문제 풀이
dx = [-1, 0, 1, 0]; # 방향
dy = [0, 1, 0, -1];
def DFS(x, y):
global cnt;
if m[x][y] == end: # 도착지
cnt += 1;
else:
for i in range(4):
xx = x + dx[i]; # 갈 좌표 값
yy = y + dy[i];
if 0 <= xx < n and 0 <= yy < n and ch[xx][yy] == 0:
if m[x][y] < m[xx][yy]: # 더 높은 구역
ch[xx][yy] = 1;
DFS(xx, yy);
ch[xx][yy] = 0;
if __name__ == "__main__":
n = int(input());
m = [list(map(int, input().split())) for _ in range(n)];
ch = [[0]* n for _ in range(n)];
start = 200;
end = 0;
for i in range(n):
for j in range(n):
if start > m[i][j]:
start = m[i][j];
if end < m[i][j]:
end = m[i][j];
cnt = 0; # 카운트
for i in range(n):
for j in range(n):
if start == m[i][j]:
ch[i][j];
DFS(i, j);
print(cnt);
문제 답안
dx = [-1, 0, 1, 0]; # 방향
dy = [0, 1, 0, -1];
def DFS(x, y):
global cnt;
if x == ex and y == ey: # 도착지점
cnt += 1;
else:
for k in range(4):
xx = x + dx[k];
yy = y + dy[k];
if 0 <= xx < n and 0 <= yy < n and ch[xx][yy] == 0 and board[xx][yy] > board[x][y]:
ch[xx][yy] = 1;
DFS(xx, yy);
ch[xx][yy] = 0;
if __name__ == "__main__":
n = int(input()); # 지도의 크기
board = [[0] * n for _ in range(n)]; # 지도 정보 초기화
ch = [[0] * n for _ in range(n)]; # 체크 리스트
max = - 2147000000; # 최댓값
min = 2147000000; # 최솟값
for i in range(n): # 입력 받으며 최솟값, 최댓값 탐색
tmp = list(map(int, input().split()));
for j in range(n):
if tmp[j] < min: # 최솟값
min = tmp[j];
sx = i;
sy = j;
if tmp[j] > max: # 최댓값
max = tmp[j];
ex = i;
ey = j;
board[i][j] = tmp[j];
ch[sx][sy] = 1; # 출발 지점
cnt = 0;
DFS(sx, sy);
print(cnt);
풀이와 답안 비교
내 코드는 for문을 너무 남발했다.
3. 단지 번호 붙이기(DFS)
문제 해설
- 이중 for문이 돌며 단지를 탐색
- 1을 발견하면 DFS를 호출해서 집 개수를 카운팅하기
- 답을 위한 리스트에 찾은 집 개수 넣기
- 단지 개수, 집 개수를 출력
- 방문한 집은 0으로 체크
- BFS로도 탐색 가능
문제 답안
dx = [-1, 0, 1, 0]; # 방향
dy = [0, 1, 0, -1];
def DFS(x, y):
global cnt;
cnt += 1; # 집 카운팅
board[x][y] = 0; # 방문 체크
for i in range(4): # 네방향
xx = x + dx[i];
yy = y + dy[i];
if 0 <= xx < n and 0 <= yy < n and board[xx][yy] == 1:
DFS(xx, yy);
if __name__ == "__main__":
n = int(input());
board = [list(map(int, input())) for _ in range(n)];
res = []; # 집, 단지
for i in range(n):
for j in range(n): # 집 탐색
if board[i][j] == 1: # 집 발견
cnt = 0; # 매 단지마다의 집의 개수
DFS(i, j);
res.append(cnt); # 단지 집 개수 저장
print(len(res)); # 단지의 개수
res.sort(); # 오름차순 정렬
for x in res: # 단지 출력
print(x);
4. 섬나라 아일랜드(BFS)
문제 해설
- 8방향 탐색
- 섬이 몇개 있는지만 갯수를 센다.
문제 답안
from collections import deque
dx = [-1, -1, 0, 1, 1, 1, 0, -1]; # 8 방향
dy = [0, 1, 1, 1, 0, -1, -1, -1];
n = int(input()); # 격자 크기
board = [list(map(int, input().split())) for _ in range(n)]; # 지도 정보
cnt = 0; # 섬 카운트
Q = deque(); # 큐 자료구조
for i in range(n):
for j in range(n):
if board[i][j] == 1:
board[i][j] = 0; # 체크
Q.append((i, j)); # 좌표 넣기
while Q:
tmp = Q.popleft();
for k in range(8): # 8방향 탐색
x = tmp[0] + dx[k];
y = tmp[1] + dy[k];
if 0 <= x < n and 0 <= y < n and board[x][y] == 1:
board[x][y] = 0; # 체크
Q.append((x, y));
cnt += 1;
print(cnt);
5. 안전영역(BFS)
문제 해설
- DFS로도 가능
- 체크 리스트 만들기 (2차원 리스트)
- 강수량에 따라 안 잠기는 지역 구하기
문제 답안
import sys
sys.setrecursionlimit(10**6); # 10**6 넘으면 재귀함수 종료
dx = [-1, 0, 1, 0];
dy = [0, 1, 0, -1];
def DFS(x, y, h):
ch[x][y] = 1; # 방문
for i in range(4): # 4방향 탐색
xx = x + dx[i];
yy = y + dy[i];
# 경계를 넘지 않고 물에 잠기지 않은 미방문 지역
if 0 <= xx < n and 0 <= yy < n and ch[xx][yy] == 0 and board[xx][yy] > h:
DFS(xx, yy, h);
if __name__ == "__main__":
n = int(input()); # 지도 크기
res = 0; # 최종 답
board = [list(map(int, input().split())) for _ in range(n)]; # 지도 정보
for h in range(100): # 0 ~ 99
ch = [[0] * n for _ in range(n)]; # 체크리스트
cnt = 0;
for i in range(n): # 탐색
for j in range(n):
if ch[i][j] == 0 and board[i][j] > h: # 물에 잠기지 않는 지점
cnt += 1; # 안전영역
DFS(i, j, h);
res = max(res, cnt) # 최댓값 입력
if cnt == 0: # 안전영역을 더 이상 발견 못하면 중단
break;
print(res);
'programming study > Algorithm' 카테고리의 다른 글
[인프런 - 김태원] 파이썬 알고리즘 문제풀이 (코딩테스트 대비) (27)(2021.2.20) (0) | 2021.02.20 |
---|---|
[인프런 - 김태원] 파이썬 알고리즘 문제풀이 (코딩테스트 대비) (26)(2021.2.19) (0) | 2021.02.19 |
[인프런 - 김태원] 파이썬 알고리즘 문제풀이 (코딩테스트 대비) (24)(2021.2.17) (0) | 2021.02.17 |
[인프런 - 김태원] 파이썬 알고리즘 문제풀이 (코딩테스트 대비) (23)(2021.2.16) (0) | 2021.02.16 |
[인프런 - 김태원] 파이썬 알고리즘 문제풀이 (코딩테스트 대비) (22)(2021.2.15) (0) | 2021.02.15 |