그리디 알고리즘
그리디 알고리즘(탐욕법)은 현재 상황에서 지금 당장 좋은 것만 고르는 방법
정당성 분석이 중요
일반적인 상황에서 그리디 알고리즘은 최적의 해를 보장할 수 없을 때가 많지만,
코딩 테스트에서 대부분의 그리디 문제는 탐욕법으로 얻은 해가 최적의 해가 되는 상황임
ex) <문제> 거스름 돈: 문제
아이디어: 가장 큰 화폐 단위부터 돈을 거슬러줌
큰 단위가 항상 작은 단위의 배수이므로 작은 단위의 동전들을 종합해 다른 해가 나올 수 없기 때문에 가장 큰 화폐 단위부터 돈을 거슬러 주는 것이 최적의 해를 보장
최소한의 아이디어를 떠올리고 정당한지 검토
n = 1260
count = 0
array = [500,100,50,10]
for coin in array:
count += n // coin #해당 화페로 거슬러 줄 수 있는 동전 개수 세기
n %= coin
print(count)
시간 복잡도는 O(k) 화폐의 개수 만큼 시간 복잡도를 가짐
ex) <문제> 1이 될 때까지
아이디어: 가능하면 최대한 많이 나누는 작업이 최적의 해
# N, K공백을 기준으로 구분하여 입력 받기
n, k = map(int, input().split())
result = 0
while True:
# N이 K로 나누어 떨어지는 수가 될 때까지만 1씩 빼기
target = (n // k) * k
result += (n - target)
n = target
# N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출
if n < k:
break
# K로 나누기
result += 1
n //= k
# 마지막으로 남은 수에 대하여 1씩 빼기
result += (n - 1)
print(result)
ex)<문제> 곱하기 혹은 더하기
아이디어: 두 수에 대하여 연산을 수행할 때, 두 수중 하나라도 1이하인 경우에는 더하고 둘 다 2 이상이면 곱하는 것이 최적의 해
data = input()
result =int(data[0])
for i in range(1, len(data)):
#두 수 중에서 하나라도 '0' 또는 '1'인 경우, 곱하기보다 더하기 수행
num = int(data[i])
if num <= 1 or result <=1:
result += num
else:
result *=num
print(result)
구현
머릿속에 있는 알고리즘을 소스코드로 바꾸는 과정
풀이를 떠올리는 것은 쉽지만 소스코드로 옮기기 어려운 문제
ex) 알고리즘은 간단한데 코드가 지나치게 길어지는 문제/
문자열을 특정한 기준에 따라서 끊어 처리해야 하는 문제
시뮬레이션 및 완전 탐색 문제에서는 2차원 공간에서의 방향 벡터가 자주 활용
ex) <문제> 상하좌우
아이디어: 요구사항대로 충실히 구현 하면됌/ 시뮬레이션 유형으로 분류
n = int(input())
x,y = 1,1
plans = input().split()
#L,R,U,D 따른 이동 방향
dx = [0,0,-1,1]
dy = [-1,1,0,0]
move_types = ['L','R','U','D']
#이동 계획을 하나씩 확인
for plan in plans:
#이동 후 좌표 구하기
for i in range(len(move_types)):
if plan == move_types[i]:
nx = x + dx[i]
ny = y + dy[i]
#공간을 벗어나는 경우 무시
if nx < 1 or ny < 1 or nx > n or ny > n:
continue
#이동 수행
x,y = nx,ny
print(x,y)
<문제> 시각문제
아이디어: 가능한 모든 시각의 경우를 하나씩 모두 세서 풀수 있는 문제, 완전 탐색 문제 유형
h = int(input())
count = 0
for i in range(h+1):
for j in range(60):
for k in range(60):
#매 시각 안에 '3'이 포함시 카운트 증가
if '3' in str(i) + str(j) + str(k):
count += 1
print(count)
<문제> 왕실의 나이트
아이디어: 요구사항대로 충실히 구현
리스트를 이용하여 8가지 방향에 대한 방향 벡터 정의 필요
# 현재 나이트의 위치 입력받기
input_data = input()
row = int(input_data[1])
column = int(ord(input_data[0])) - int(ord('a')) + 1
# 나이트가 이동할 수 있는 8가지 방향 정의
steps = [(-2, -1), (-1, -2), (1, -2), (2, -1), (2, 1), (1, 2), (-1, 2), (-2, 1)]
# 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인
result = 0
for step in steps:
# 이동하고자 하는 위치 확인
next_row = row + step[0]
next_column = column + step[1]
# 해당 위치로 이동이 가능하다면 카운트 증가
if next_row >= 1 and next_row <= 8 and next_column >= 1 and next_column <= 8:
result += 1
print(result)
<문제> 문자열 재정렬
아이디어: 리스트에 저장된 알파벳을 정렬하여 출력하고, 합계를 뒤에 붙여 출력하면 정답
data = input()
result = []
value = 0
#문자열 하나씩 확인
for x ind ata:
# 알파벳인 경우 결과 리스트에 삽입
if x.isalpha():
result.append(x)
# 숫자는 따로 더하기
else:
value += int(x)
# 알파벳을 오름차순으로 정렬
result.sort()
#숫자가 하나라도 존재 시 가장 뒤에 삽입
if value != 0:
result.append(str(value))
#최종 결과 출력(리스트를 문자열로 변환하여 출력)
print(''.join(result))
Uploaded by Notion2Tistory v1.1.0