🌼 DFS(Depth-First-Search) Algorithm

  • DFS는 깊이 우선 탐색이라고도 부르며, 그래프의 깊은 부분을 우선적으로 탐색하는 알고리즘이다.
  • DFS는 Stack 자료구조(혹은 재귀함수)를 이용하며, 구체적인 동작 과정은 다음과 같다.
    1. 탐색 시작노드를 스택에 넣고, 방문처리한다.
    2. 스택의 최상단 노드와 인접한 노드 중 방문하지 않은 노드가 있다면, 그 노드를 스택에 넣고 방문처리한다. 방문하지 않은 인접 노드가 없다면 스택 최상단 노드를 pop한다.
    3. 2번의 과정을 수행할 수 없을때까지(stack이 empty할때까지) 반복한다.

 

🌼 재귀함수로 DFS 구현

# DFS 메서드 정의
def dfs(graph, v, visited):
	# 현재 노드를 방문 처리
    visited[v] = True
    print(v, end=' ')
    
    # 현재 노드와 연결된 다른 노드를 재귀적으로 방문
    for i in graph[v]:
    	if not visited[i]:
        	dfs(graph, i, visited)

# 각 노드가 연결된 정보를 표현(2차원 배열)
graph = [
	[],
    [2, 3, 8],
    [1, 7],
    [1, 4, 5],
    [3, 5],
    [3, 4],
    [7], 
    [2, 6, 8],
    [1, 7]
]

# 각 노드가 방문된 정보를 표현 (1차원 리스트)
visited = [False] * 9

# 정의된 DFS 함수 호출
dfs(graph, 1, visited)

# 실행 결과
# 1 2 7 6 8 3 4 5

 

🌼 재귀함수로 DFS 구현

# DFS 메서드 정의
def dfs(graph, v):
    visited = [False] * len(graph)
    stack = []
    stack.append(v)

    while stack:
        v = stack.pop()

        if not visited[v]:
            print(v, end=' ')
            visited[v] = True

        for w in sorted(graph[v], reverse=True):
            if not visited[w]:
                stack.append(w)

# 각 노드가 연결된 정보를 표현(2차원 배열)
graph = [
    [],
    [2, 3, 8],
    [1, 7],
    [1, 4, 5],
    [3, 5],
    [3, 4],
    [7],
    [2, 6, 8],
    [1, 7]
]

# 정의된 DFS 함수 호출
dfs(graph, 1)

# 실행 결과
# 1 2 7 6 8 3 4 5
728x90

이것이 코딩테스트다 with 파이썬

🌼 Greedy Algorithm (탐욕 알고리즘)

  • 현재 상황에서 지금 당장 좋은 것만 고르는 방법
  • 일반적인 상황에서 그리디 알고리즘은 최적의 해를 보장할 수 없다. >> 정당성 분석이 중요!
  • 그러나 코테 문제에서는 일반적으로 탐욕법으로 얻은 해가 최적의 해가 되는 상황에서 이론 추론해야 풀리도록 출제
  • 대표적인 그리디 알고리즘 문제 - 거스름돈 문제

 

📄 <문제1> 1이 될 때까지: 문제 설명

어떠한 수 N이 1이 될 때까지 다음의 두 과정 중 하나를 반복적으로 선택하여 수행하려고 함.

단, 두 번째 연산은 N이 K로 나누어 떨어질 때만 선택할 수 있음.

1. N에서 1을 뺀다.

2. N을 K로 나눈다.

ex) N이 17, K가 4라고 가정. 이때 1번의 과정을 한 번 수행하면 N은 16이 된다. 이후에 2번의 과정을 두 번 수행하면 N은 1이 된다. 결과적으로 전체 과정을 실행한 횟수는 3 이 된다. 

N과 K가 주어질 때 N이 될 때 까지 1번 혹은 2번의 과정을 수행해야 하는 최소 횟수를 구하는 프로그램 작성

# N, K을 공백을 기준으로 구부낳여 입력 받기
N, K = map(int, input().split())

result = 0

while True:
	# N이 K로 나누어 떨어지는 수가 될 때까지 빼기
    target = (N // K) * K
    result += (n - target)
    
    n = target
    # N이 K보다 작을 때(더 이상 K로 나눌 수 없을 때) 반복문 탈출
    if N < K:
    	break
        
    # K로 나누기
    result += 1
    N //= K
# 마지막으로 남은 수에 대하여 1씩 빼기
result += (N -1)
print(result)

 

 

📄 <문제2> 곱하기 혹은 더하기: 문제 설명

각 자리가 숫자(0부터 9)로만 이루어진 문자열 S가 주어졌을 때, 왼쪽부터 오른쪽으로 하나씩 모든 숫자를 확인하며 숫자 사이에 'x' 혹은 '+' 연산자를 넣어 결과적으로 만들어질 수 있는 가장 큰 수를 구하는 프로그램 작성

단, +보다 x를 먼저 계산하는 일반적인 방식과는 달리, 모든 연산은 왼쪽에서부터 순서대로 이루어진다고 가정

ex) 02984 라는 문자열로 만들 수 있는 가장 큰 수는 ((((0+2) * 9) * 8) * 4) = 576입니다. 또한 만들어질 수 있는 가장 큰 수는 항상 20억 이하의 정수가 되도록 입력이 주어진다.

 

  • 대부분의 경우 '+' 보다는 'x'가 더 값을 크게 만듬.
  • 두 수 중에서 하나라도 '0' 혹은 '1'인 경우, 곱하기보다 더하기를 수행하는 것이 효율적
  • 따라서 두 수에 대하여 연산을 진행할 때, 두 수 중에서 하나라도 1 이하인 경우에는 더하며, 두 수가 모두 2 이상인 경우에는 곱하면 정답
strings = list(map(int, input().strip()))

result = 0

for s in strings:
    if s <= 1 or result <= 1:
        result += s
    else:
        result *= s
print(result)

 

 

📄 <문제3> 모험가 길드: 문제설명

한 마을에 모험가가 N명이 있다. 모험가 길드에서는 N명의 모험가를 대상으로 '공포도'를 측정했는데, '공포도'가 높은 모험가는 쉽게 공포를 느껴 위험 상황에서 제대로 대처할 능력이 떨어진다.

모험가 길드장인 00이는 모험가 그룹을 안전하게 구성하고자 공포도가 X인 모험가는 반드시 X명 이상으로 구성한 모험가 그룹에 참여해야 여행을 떠날 수 있도록 규정했다.

  • 풀이 방법
    1. 공포도 오름차순 정렬
    2. 앞에서부터 공포도를 하나씩 확인하며 '현재 그룹에 포함된 모험가의 수'가 '현재 확인하고 있는 공포도' 보다 크거나 같다면 이를 그룹으로 설정하면 된다.
n = int(input())
data =list(map(int, input().split()))
data.sort()

result = 0 # 총 그룹의 수
count = 0 # 현재 그룹에 포함된 모험가의 수

for i in data: # 공포도를 낮은 것부터 하나씩 확인하며
	count += 1 # 현재 그룹에 해당 모험가를 포함시키기
    if count >= i: # 현재 그룹에 포함된 모험가의 수가 현재의 공포도 이상이라면, 그룹 결성
    	result += 1 # 총 그룹의 수 증가
        count = 0 # 현재 그룹에 포함된 모험가의 수 초기화
print(result)
728x90

🌼 실전에서 자주 사용되는 표준 라이브러리

1. itertools: 반복되는 형태의 데이터 처리를 위한 함수 제공

  • ex) 순열 조합

2. heapq: 힙(Heap) 자료구조 제공

  • 일반적으로 우선순위큐 구현시 사용

3. bisect: 이진 탐색(Binary Search) 기능을 제공

4. collections: 데크(dequeue), 카운터(Counter) 등의 자료구조 제공

5. amth: 필수적인 수학적 기능 제공

  • ex) 팩토리얼, 최대 공약수(GDC), 최소 공배수(LCM), 파이(Pi) 등 제공

 

🌼 순열과 조합 - itertools 라이브러리

  1. 순열 (permutations)
    • 서로 다른 n개에서 서로 다른 r개를 선택하여 일렬로 정렬(순서 고려)
    • 중복고려 버전 > product()
  2. 조합 (combinations)
    • 서로 다른 n개에서 서로 다른 r개를 선택 (순서 고려 X)
    • 중복고려 버전 > combinations_with_replacement()

 

🌼 Counter - collections 라이브러리

  • 등장 횟수를 세는 라이브러리
from collections import Counter

arr = ['blue', 'blue', 'red', 'blue', 'red', 'yellow', 'blue']
counter = Counter(arr)

print(counter['red'])
print(counter['blue'])
print(counter['yellow'])
print(dict(counter))

# 출력 결과
# 2
# 4
# 1
# {'blue': 4, 'red': 2, 'yellow': 1}

 

🌼  최대공약수와 최소공배수 - math 라이브러리

  • 최대공약수 - GCD
  • 최소공배수 - LCM
728x90

+ Recent posts