이것이 취업을 위한 코딩 테스트다. with 파이썬 - 나동빈
public class LawOfLargeNumbers {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int answer = 0;
String str = br.readLine();
String[] split = str.split(" ");
int N = Integer.valueOf(split[0]);
int M = Integer.valueOf(split[1]);
int K = Integer.valueOf(split[2]);
int[] arr = new int[N];
for(int i = 0; i < N; i++) {
StringTokenizer stringTokenizer = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(stringTokenizer.nextToken());
}
Arrays.sort(arr);
int first = arr[N - 1];
int second = arr[N - 2];
int temp = K;
for(int i = 0; i < M; i++) {
if(temp != 0) {
answer += first;
} else {
answer += second;
temp = K;
}
temp--;
}
System.out.println(answer);
}
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int answer = 0;
String str = br.readLine();
String[] split = str.split(" ");
int N = Integer.valueOf(split[0]);
int M = Integer.valueOf(split[1]);
int K = Integer.valueOf(split[2]);
int[] arr = new int[N];
for(int i = 0; i < N; i++) {
StringTokenizer stringTokenizer = new StringTokenizer(br.readLine());
arr[i] = Integer.parseInt(stringTokenizer.nextToken());
}
Arrays.sort(arr);
int first = arr[N - 1];
int second = arr[N - 2];
int temp = K;
for(int i = 0; i < M; i++) {
if(temp != 0) {
answer += first;
} else {
answer += second;
temp = K;
}
temp--;
}
System.out.println(answer);
문제를 이렇게 for 문을 돌려서 풀 수도 있지만, M 의 값이 엄청나게 크다면, 이러한 방법은 시간 초과 판정을 받을 것이다. 그러므로 간단한 수학적 아이디어가 필요했다.
이 문제를 보면 반복되는 패턴이 있다는 것을 확인할 수 있다.
이러한 형태로 일정하게 반복해서 더해지는데, 위의 예에서는 (6 + 6 + 6 + 5) 가 반복되고 있다.
그렇다면 반복되는 수열의 길이는? K + 1 = 4가 되고, M / (K + 1) = 수열의 반복 횟수가 된다. 다시 이 반복 횟수에 K 를 곱해주면 가장 큰 수를 더하는 횟수가 나오게 된다.
이 때 M 이 (K + 1) 로 나누어지지 않는 경우도 있다. 이 경우에는 M 을 (K + 1) 로 나눈 나머지 만큼 가장 큰 수가 더해지기 때문에, M % (K + 1) 를 더하는 횟수에 추가하면 된다.
그다음 큰 수는 (M - 가장 큰 수를 더하는 횟수) 를 하면 저절로 구해진다.
int count = (M / (K + 1)) * K;
count += (M % (K + 1));
answer += first * count;
answer += (M - count) * second;