현재 상황에서 지금 당장 좋은 것만 고르는 방법
을 의미[문제 상황] 루트노드부터 시작하여 거쳐가는 노드 값의 합을 최대로 만들고 싶습니다.
5 ->7->9 정답 : 21
5->10->14, 합: 19
결국 일반적인 상황에서 그리디 알고리즘은 100%정답이라고 보장 할 수 없습니다.
하지만 코테에서는 대부분의 그리디 문제는 탐욕법으로 얻은 해가 최적의 해가 되는 상황에서, 이를 추론할 수 있어야 풀리도록 출제되요.
가장 큰 화폐 단위부터
돈을 거슬러 줍니다.큰 단위가 항상 작은 단위의 배수이므로 작은 단위의 동전들을 종합해 다른 해가 나올 수 없기 때문
n =1260e10000
count =0
array=[500,100,50,10]
for coin in array:
count += n//coin # 해당 화폐로 거슬러 줄수 있는 동전의 개수 세기
n %= coin
print(count)
하나. 내림차순으로 정렬되어 있어야 위 문제에서 설계된 정답을 낼수 있습니다. 만약 오름차순으로 된다면 126개의 동전을 거슬러주는 알고리즘이 되어버립니다.
다시 말해 가장 동전을 많이 거슬러줄 수 있는 방법이 되버립니다.
동전의 총 종류
에만 영향을 받습니다.
단계 | 과정 | N의값 |
---|---|---|
0단계 | N = 25 | |
1단계 | N에서 1빼기 | N = 24 |
2단계 | N을 K로 나누기 | N = 8 |
3단계 | N에서 1빼기 | N = 7 |
4단계 | N에서 1빼기 | N = 6 |
5단계 | N을 K로 나누기 | N = 2 |
6단계 | N에서 1빼기 | N = 1 |
입력값 = 25, 3
25-1 = 24
24//3 = 8
8-1 = 7
7-1 = 6
6//3= 2 # 여기서 나머지가 0이 된다고 끝나는게 아니라 몫을 받아와서 연산하는 것이므로 주의해야함
2-1=1
n, k = map(int, input().split())
result = 0
while True:
#N이 K로 나누어 떨어지는 수가 될 때까지 빼기
target = (n//k) * k
result += (n-target) # 0 + (25-24) -> 1
n = target # 25 = 24 -> 24
# N이 K보다 작을 때 (더 이상 나눌 수 없을 때) 반복문 탈출
if n < k:
break
# k로 나누기
result += 1
n //= k
# 마지막으로 남은 수에 대하여 1씩 빼기
result +=(n - 1)
print(result)
target = (n//k) * k
이 부분은 만약 n이k로 나누어 떨어지지 않는다고 해도 가장 가까운 k로 나누어 떨어지는 어떤 수
를 찾을 수 있어요.
즉, n에서 1을 빼는 과정을 몇번 반복해서 target
이라는 값까지 만들 수 있고 target
이라는 값은 k
로 나누어 떨어지는 수가 되요.
result += (n-target)
부분은 우리가 총 연산을 수행하는 횟수를 의미해요.
if n < k:
while문을 벗어나고, 그렇지않다면 남은 연산을 수행하게되요.
상기 알고리즘 방법은 반복횟수에 따라서 기하급수적으로 n
이 빠르게 줄어들게되요.
즉, 시간 복잡도가 시간 복잡도가 나올수 있게되요. 그래서 이 알고리즘은 어느정도 테크닉이 가미된 부분이에요.
n이 100억 1000억이 넘는 큰 수라고 하더라도 시간 복잡도로 빠르게 해결 할 수 있어요.
import sys
data = sys.stdin.readline().rstrip()
# 처음 문자를 숫자로 변경하여 대입
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)
2,3,1,2,2
import sys
data = list(map(int, sys.stdin.readline().rstrip().split()))
data.sort()
groups = 0 # 총 그룹의 수
group_member = 0 # 현재 그룹에 포함된 모험가의 수
for volatility_index in data: # 공포도를 낮은 것부터 하나씩 확인하며
group_member +=1 # 현재 그룹에 해당 모험가를 포함시키기
if group_member >= volatility_index: # 현재 그룹에 포함된 모험가의 수가 현재 공포도 이상이라면, 그룹 결성
groups += 1 # 총 그룹의 수 증가 시키기
group_member = 0 # 현재 그룹에 포함된 모험가의 수 초기화
print(groups)
입력 조건을 통해서 그룹은 최소 1명이상은 된다는거에요.
정렬된 리스트 변수 data에서 예) [1,2,2,2,3]에서 지역 변수 i에 대입해서 루프가 돌아가요.
count는 그룹에 모험가를 포함시킨다고 했으니깐.
공포도가 1인 모험가는 조건문에 진입하기전 포함됩니다.
조건문에서는 count(그룹에 포함된 모험가<공포도1> 인원 수)
가 i보다 이상이면 분기가 정상적으로 돌아가도록 했는데요.
여기서 i는 공포도입니다.
다시 한번 더 count는 현재 그룹에 포함된 모험가의 수
V.S. 현재 모험가의 공포도
를 비교합니다.
A >= B
와 같은 구조적 상황이면 당근 분기문안으로 빠져 들어갑니다.
들어간다고 치면 result가 1이 증가하는데요. 여기서 result
변수는 몇개 그룹인지 수를 알려줘요.
그런데 다음이 count=0
으로 하네요? 중요한건 공포도와 그룹 형성의 상관관계입니다.
즉, 최대 많은 그룹을 만들어야하고 공포도가 작은 인원이 그룹을 만들기에 매우 좋다는 사실! 공포도가 1이면 그룹1개 만들어서 그냥 사냥하러 나가면 된다는 겁니다. 이런 구조적 상황을 더 설명하면 공포도가 100이면 그룹인원이 100명이 되어야 사냥하러 갈 수 있다는 말이 됩니다. 해당 그룹에 참여한 파티원 한명의 공포도 <= 현재 그룹인원수
헷갈리조?
만약 처음 공포도가 1인 사람이 나오고 두번째 인원이 100이라고 가정한다면 다음 인원은 100 이상이어야 합니다. 그래야 문제를 풀 수 있어요. 오름차순으로 정렬되어 있지 않으면 의도한 결과나 나타나지 않아요.
만약 정렬이 안되고 루프가 돌아간다면 예) 5,4,3,2,1의 경우 결과가 2가 나와요
논리적으로는 공포도가 5인 녀석은 반드시 5명이상만 꾸릴수 있고.
4인 녀석도 인원이 4명 이상만 가능하고
3도, 2도, 1도. 동일합니다. 그래서 논리적으로는 팀은 1개팀만 가능해요. (5,4,3,2,1) 또는 (4,3,2,1), 또는 (3,2,1) 또는 (2,1) 또는 (1,) 그런데 막상 오름차순으로 정렬하지 않고 내림차순으로 하게되면 팀이 2개가 됩니다.
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 입력 받기
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)
참고로 벡터란? (화살표로 그려지는)벡터에는 크기(화살표의 길이)와 방향(화살표가 가리키는 방향)이 있습니다.
참고로 벡터란? (화살표로 그려지는)벡터에는 크기(화살표의 길이)와 방향(화살표가 가리키는 방향)이 있습니다.
input_data = input() # ex 'a1'
row= int(input_data[1]) # 'a1' -> '1' -> 1 현재 나이트의 로우 위치 문자를 정수로 바꿈
column= ord(input_data[0]) - ord('a') + 1 #
# input_data[0]은 'a' 알파벳인 컬럼을 의미
# 그 알파벳이 ord() 메서드를 통해서 유니코드 문자를 대표하는 정수를 반환함
# 예 'a' -> 97 반환
# 정리하면 문자 a를 유니코드함수에 집어 넣으면 정수 97을 반환함.
# 이후 97- 고정된 문자'a'의 유니코드 반환 정수를 빼면 당근 97-97 이므로 0이된다.
# 그런데 뒤에 1을 넣었으므로 결과적으로 문자를 입력한 'a1'은 정수 1로 컬럼위치를 확인 할 수 있게 된다.
# 즉 a~h로 문자로 표기된 것을 십진수 숫자로 최종적으로 계산하기 위한 방법임.
# 나이트가 이동할 수 있는 8가지 방향 정의
# 만약 'a1'을 입력하면 -> (1,1)
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)
> (x,y) == (row, column)으로 표기한다는 기본 전제
(x-2,y)
가 됨 더불어!! 위로 1칸 올라가면 결론적으로 ->(x-2, y+1)
변화되는 값을 보면 결국 (-2, +1)
(x-1,y)
가 됨 더불어!! 아래로 1칸 내려 가면 결론적으로 ->(x-2, y+1)
변화되는 값을 보면 결국 (-2, -1)
(-1, -2)
(1, -2)
(2, -1)
(2, 1)
(1, 2)
(-1, 2)
하지만 그 가능성도 실제적인 8*8 이라는 공간에서 제한을 받조?
data = input()
result = [] # 알파벳을 담을 리스트 변수
value = 0 # 숫자를 총 합산해서 반환 할 변수
# 문자를 하나씩 확인
for x in data:
# 알파벳인 경우 결과 리스트에 삽입
if x.isalpha():
result.append(x)
# 숫자는 따로 더함
else:
value += int(x)
# 알파벳을 오름차순으로 정렬
result.sort()
# 숫자가 하나라도 존재하는 경우 가장 뒤에 삽입
if value !=0
result.append(str(value))
# 최종 결과 출력(리스트를 문자열로 변환하여 출력)
print(''.join(resut))