https://github.com/Dev-Guccin
Guccin
https://github.com/Dev-Guccin
전체 방문자
오늘
어제
  • 분류 전체보기 (172)
    • 알고리즘 (140)
    • 삽질방지 (13)
    • SystemHacking (1)
    • 일상 (4)
    • 개발 (8)
    • 스프링 부트 REST API 개발일지 (5)
    • JPA (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • BFS
  • 재귀
  • 그리디
  • 그래프
  • 백준
  • LIS
  • 최대공약수
  • 다이나믹프로그래밍
  • Python
  • 이분 탐색
  • 프로그래머스
  • 12015
  • counter
  • DP
  • 다이나믹 프로그래밍
  • 이분탐색
  • 다익스트라
  • 파이썬
  • heapq
  • 최단경로
  • 백트래킹
  • DFS
  • 스택
  • 최소힙
  • MST
  • python3
  • 큐
  • 재귀함수
  • 유클리드호제법
  • 유니온 파인드

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
https://github.com/Dev-Guccin

Guccin

알고리즘

백준 1987 파이썬 풀이 (알파벳, DFS)

2021. 7. 17. 18:13

기존에 DFS,BFS문제는 주어진 미로에서 가장 짧은 길을 찾거나 걸리는 시간을 주로 구했다. 그런데 이번 문제는 미로가 아닌 각 칸에 알파벳이 주어질때 가장 멀리까지 가는 경우 몇칸이나 지나갈 수 있는지 구하는 것이다.

기존과 달리 모든 경우를 살펴보아야 구할 수 있다.

 

1. DFS로 각 칸은 상하좌우 확인한다.

2. 이때까지 지나온 알파벳과 중복되지 않으면 갈 수 있다.(즉, 해당 경로 혹은 지나왔는지 체크가 되어 있어야 한다.)

 

이렇게 2가지 조건을 통해 코딩을 진행했다. 

r, c = map(int, input().split())
M = []
for i in range(r):
    tmp = list(input())
    M.append(tmp)

alpha = [0]*26
alpha[ord(M[0][0])-65] = 1
s = [[[0, 0], alpha]]
count = 1
dx = [0, 0, 1, -1]  # 동서남북
dy = [1, -1, 0, 0]
while s:
    point, path = s.pop()
    print("point:", point)
    x, y = point
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]
        if (0 <= nx < r) and (0 <= ny < c) and (path[ord(M[nx][ny])-65] == 0):
            newpath = list(path)
            newpath[ord(M[nx][ny])-65] = 1
            s.append([[nx, ny], newpath])
            if count < sum(newpath):
                count = sum(newpath)
print(count)

이때 짠 코드를 보면 몇가지 문제점이 있다. 중복으로 stack에 저장된 경우를 판별 할 수 없다. 스택에 path배열이 26짜리가 들어가게 되며 list를 그대로 복사하기 때문에 시간이 오래 걸릴 수 있다.

 

고수의 코드를 보면 애초에 stack을 리스트가 아닌 set()으로 설정하고 이때 경로를 문자열로 넣어서 이중배열을 만들지 않고 유지하게 만든다. 

dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
def bfs():
    result = 1
    queue = set([(0, 0, board[0][0])])

    while queue:
        x, y, visited = queue.pop()
        for i in range(4):
            nx = x + dx[i]
            ny = y + dy[i]
            if nx < 0 or nx >= r or ny < 0 or ny >= c:
                continue
            elif board[nx][ny] not in visited:
                next_visited = visited + board[nx][ny]
                queue.add((nx, ny, next_visited))
                result = max(result, len(next_visited))
    return result

r, c = map(int, input().split())
board = []
for i in range(r):
    board.append(list(input()))
print(bfs())

이러한 경우 시간이 훨씬 많이 줄어들게 된다.

'알고리즘' 카테고리의 다른 글

백준 10026 파이썬 풀이 (적록색약, DFS)  (0) 2021.07.17
백준 2583 파이썬 풀이 (영역 구하기, DFS)  (0) 2021.07.17
백준 2206 파이썬 풀이 (BFS, 벽 부수고 이동하기, 이차 배열 사용)  (0) 2021.07.12
백준 1707 python 풀이 (이분 그래프, BFS)  (0) 2021.07.11
백준 7562 python 풀이 (나이트의 이동, BFS, 그래프)  (0) 2021.07.10
    '알고리즘' 카테고리의 다른 글
    • 백준 10026 파이썬 풀이 (적록색약, DFS)
    • 백준 2583 파이썬 풀이 (영역 구하기, DFS)
    • 백준 2206 파이썬 풀이 (BFS, 벽 부수고 이동하기, 이차 배열 사용)
    • 백준 1707 python 풀이 (이분 그래프, BFS)
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin
    https://github.com/Dev-Guccin

    티스토리툴바