< 큰 수의 법칙 >
난이도 : 하
[문제]
동빈이의 큰 수의 법칙은 다양한 수로 이루어진 배열이 있을 때 주어진 수들을 M번 더하여 가장 큰 수를 만드는 방법이다. 단, 배열의 특정한 인덱스에 해당하는 수가 연속해서 K번을 초과하여 더해질 수 없는 것이 이 법칙의 특징이다.
예를 들어 순서대로 2, 4, 5, 4, 6으로 이루어진 배열이 있을 때, M이 8이고 K가 3이라고 가정하자.
이 경우 특정한 인덱스의 수가 연속해서 세 번까지만 더해질 수 있으므로 큰 수의 법칙에 따른 결과는 6 + 6 + 6 + 5 + 6 + 6 + 6 + 5인 46이 된다. 단, 서로 다른 인덱스에 해당하는 수가 같은 경우에도 서로 다른 것으로 간주한다.
예를 들어 순서대로 3, 4, 3, 4, 3으로 이루어진 배열이 있을 때 M이 7이고 K가 2라고 가정하자. 이 경우 두 번째 원소에 해당하는 4와 네 번째 원소에 해당하는 4를 번갈아 두 번씩 더하는 것이 가능하다.
결과적으로 4 + 4 + 4 + 4 + 4 + 4 + 4 인 28이 도출된다.
배열의 크기 N, 숫자가 더해지는 횟수 M, 그리고 K가 주어질 때 동빈이의 큰 수의 법칙에 따른 결과를 출력하시오.
[입력 조건]
- 첫째 줄에 N(2 <= N <= 1000), M(1 <= M <= 10000), K(1 <= K <= 10000)의 자연수가 주어지며 각자 연수는 공백으로 구분한다.
- 둘째 줄에 N개의 자연수가 주어진다. 각 자연수는 공백으로 구분한다.
단, 각각의 자연수는 1 이상 10000 이하의 수로 주어진다.
입력으로 주어지는 K는 항상 M보다 작거나 같다.
[출력 조건]
- 첫째 줄에 동빈이의 큰 수의 법칙에 따라 더해진 답을 출력한다.
[입력 예시] [출력 예시]
5 8 3 46
2 4 5 4 6
영규's 코드
N, M, K = map(int, input().split())
nums = list(map(int, input().split()))
nums.sort()
sum = 0
# 연속 횟수 계산
continuous_cnt = 0
for i in range(M):
# K번 연속 계산 했으면
if continuous_cnt == K:
continuous_cnt = 0
sum += nums[-2]
# 아직 K번 계산 안 했으면
else :
continuous_cnt += 1
sum += nums[-1]
print(sum)
단순무식하게 반복하여 더하는 알고리즘이다. 이 다음은 조금 더 똑똑한 코드를 작성해보았다.
영규's 코드
N, M, K = map(int, input().split())
nums = list(map(int, input().split()))
nums.sort()
cnt_idx2 = M // (K + 1) # 두 번째로 큰 수는 M // (K + 1)번 더해짐.
sum = nums[-2] * cnt_idx2
sum += nums[-1] * (M - cnt_idx2) # 그 외는 모두 첫 번째로 큰 수.
print(sum)
두 번째로 큰 수와 제일 큰 수가 몇 번씩 등장하는지를 계산하여 푸는 알고리즘이다.
'공부 > 이것이 코딩테스트다' 카테고리의 다른 글
재귀함수 이론 (0) | 2023.01.03 |
---|---|
스택과 큐 자료구조 이론 (0) | 2023.01.03 |
그리디 알고리즘 - 1이 될 때까지 (0) | 2023.01.03 |
그리디 알고리즘 - 숫자 카드 게임 (0) | 2023.01.03 |
그리디 알고리즘 이론 (1) | 2023.01.01 |