어디까지 갈 수 있을까?

chapter 3. 그리디 본문

알고리즘/이것이취업을위한코딩테스트다

chapter 3. 그리디

_Min 2021. 2. 9. 20:46

현재 상황에서 지금 당장 좋은 것만 거르는 방법

문제 상에 '가장 큰 순서대로', '가장 작은 순서대로' 와 같은 기준 제시

 

1. 거스름돈

 카운터에는 거스름돈으로 사용할 500원, 100원, 50원, 10원짜리 동전이 무한히 존재한다고 가정한다. 손님에게 거슬러 줘야 할 돈이 N원일 때 거슬러 줘야 할 동전의 최소 개수를 구하라

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import sys
input=sys.stdin.readline
 
n=int(input())
coin=[5001005010]
result=0
 
for c in coin:
    if n==0:
        break
    result+=n//c
    n%=c
 
print(result)
cs

 

2. 큰 수의 법칙

입력 예시

5 8 3

2 4 5 4 6 

 

출력 예시

46 

 

* 6 + 6 + 6 + 5 + 6 + 6 + 6 + 5  =  46

 

처음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import sys
input=sys.stdin.readline
 
n, m, k=map(int, input().split()) #합횟수, 연속
arr=list(map(int, input().split()))
arr.sort()
result=0
# print(arr)
while 1:
    result+=arr[-1]*k
    m-=k
    
    if m!=0:
        result+=arr[-2]
        m-=1
    if m==0:
        break
 
print(result)
cs

 

보완 - 반복문 안 쓰고

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# N, M, K를 공백을 기준으로 구분하여 입력 받기
n, m, k = map(int, input().split())
# N개의 수를 공백을 기준으로 구분하여 입력 받기
data = list(map(int, input().split()))
 
data.sort() # 입력 받은 수들 정렬하기
first = data[n - 1# 가장 큰 수
second = data[n - 2# 두 번째로 큰 수
 
# 가장 큰 수가 더해지는 횟수 계산
count = int(m / (k + 1)) * k
# 반복 수열의 나머지 값
count += m % (k + 1)
 
result = 0
result += (count) * first # 가장 큰 수 더하기
result += (m - count) * second # 두 번째로 큰 수 더하기
 
print(result) # 최종 답안 출력
cs

 

합횟수 10(=m), 연속 가능한 횟수 3(=k) 이라고 생각해보자

가장 큰 수가 6이고 그 다음으로 큰 수가 5라고 할 때

6+6+6+5+6+6+6+5+6+6이 되어야 한다.

 

6+6+6+5 는 계속 반복되게 된다. 다시말해 (6+6+6+5)+(6+6+6+5)+6+6 가 된다

여기서 반복되는 수열의 갯수(=()의 반복 횟수)를 구하기 위해 k+1에서 합 횟수를 나누어주면 2가 나오게 되고 

각각의 수열에는 6이 3개씩 포함되므로 3으로 나누어주면 6이 나온다.

나누기는 길이 m에 길이 k+1이 몇 번 들어갈 수 있는지 알려주는 개념으로 생각하면 편하다.

 

이제 ()가 아닌 6+6의 개수를 구하기 위해서는 *전체%반복되는 수열의 길이를 해주면 된다

그러면 2가 나오고, 최종적으로 6이 반복되는 횟수는 8번 이라는 것을 알 수 있다

 

3. 숫자 카드 게임

입력 예시

3 3 

3 1 2

4 1 4

2 2 2

 

출력 예시

2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
input=sys.stdin.readline
 
#행에서 가장 숫자가 낮은 카드 뽑기
#그 중 가장 높은 숫자의 카드를 뽑기
n, m=map(int, input().split()) #행, 열
arr=[]
result=0
for _ in range(n):
    arr.append(list(map(int, input().split())))
 
for i in range(n):
    min_value=min(arr[i])
    if min_value>result:
        result=min_value
 
print(result)
cs

 

 

4. 1이 될 때까지

입력 예시

2 5

 

출력 예시

2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import sys
input=sys.stdin.readline
 
#N에서 1을 뺀다
#N을 K로 나눈다
#N이 1이 될 때까지 수행해야 하는 횟수의 최솟값
 
n, k=map(int, input().split())
result=0
 
while n!=1:
    if n%k==0:
        result+=1
        n//=k
    else:
        n-=1
        result+=1
 
print(result)
cs

 

 

 

출처 : 이것이 취업을 위한 코딩 테스트다 with 파이썬 (나동빈 저)

 

728x90

'알고리즘 > 이것이취업을위한코딩테스트다' 카테고리의 다른 글

chapter 6. 정렬  (0) 2021.02.15
DFS/BFS 문제  (0) 2021.02.15
chapter 5. DFS/BFS  (0) 2021.02.13
그리디, 구현 문제  (0) 2021.02.13
chapter 4. 구현  (0) 2021.02.13
Comments