[BRUTEFORCE] Brute-Force Attack
Java 로 풀어보는 알고리즘입니다. 📖
코딩테스트를 대비하여 JAVA1.8 부터 제공되는 함수형 API 는 사용하지 않았습니다.
문제 : https://www.algospot.com/judge/problem/read/BRUTEFORCE
풀이입니다. 🤔
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
import java.util.*;
public class Main {
private static final int MODIFIER = 1000000007;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int cases = scanner.nextInt();
while (cases-- > 0) {
int a = scanner.nextInt(), b = scanner.nextInt(), n = scanner.nextInt();
System.out.println(solve(n, a, b));
}
}
// logN 복잡도로 pow 연산을 수행하는 알고리즘
private static long pow(int n, int count) {
if (count == 0) return 1;
if (count == 1) return n;
long acc = pow(n, count / 2) % MODIFIER;
acc = (acc * acc) % MODIFIER;
return (count % 2 == 0) ? acc : (acc * n) % MODIFIER;
}
// min 이 max 보다 작을 때, 다음 식을 구한다.
// n^(min) + n^(min+1) + n^(min+2) + n^(min+3) .... + n^(max)
private static long solve(int n, int min, int max) {
// 식을 변환 : n^(min) * (1 + n + n^2 + n^3 + ... n^(max - min))
if (min != 0) return (pow(n, min) * solve(n, 0, max - min)) % MODIFIER;
// 기저사례 1 : max 와 min 이 동일한 경우는 1 밖에 없음.
if (max == min) return 1;
// 1 + n + n^2 ... + n^m 의 절반으로 분할 후, 아래와 같은 식으로 나눈다.
// (1 + n + n^(m/2)) + n^(length / 2) * (1 + n + n^(m/2))
// (1 + n + n^(m/2)) 에 해당하는 결과가 동일하게 나타나기 때문에 1 회 연산 후 합친다.
int length = (max - min + 1);
long acc = solve(n, min, ((max % 2 == 0) ? max - 1 : max) / 2);
long accPow = (pow(n, length / 2) * acc) % MODIFIER;
acc = (acc + accPow) % MODIFIER;
return (length % 2 == 0) ? acc : (acc + pow(n, length - 1)) % MODIFIER;
}
}
|
cs |
문제에서 요구하는 사항은 입력된 a, b, n 에 대하며 다음의 식에 대한 답을 원합니다.
f(n, a, b) = n^(a) + n^(a + 1) + n^(a + 2) ..... + n^(b)
이 식은 중간에서 분할 후, 공통된 연산을 찾아 두번 계산하지 않는 것으로 최적화 할 수 있습니다.
f(n, a, b)
= n^(a) * ( 1 + n + n^2 + n^3 + .... n^(b - a))
= n^(a) * ( (1 + n + n ^2 ... n^(b - a) / 2) + n^((b - a + 1) / 2) * (1 + n + n ^2 ... n^(b - a) / 2))
해당 식을 재귀적으로 실행시키면서, 총 덧셈을 해야할 숫자의 갯수가 홀수일 때와 계산된 값이 오버플로우하지 않게 MOD 연산을 수행하면문제를 해결할 수 있습니다.
이 포스트를 읽어주셔서 감사합니다. 🙇🏻♂️
'개발이야기 > 알고스팟' 카테고리의 다른 글
[FENCE] 울타리 잘라내기 (0) | 2022.01.14 |
---|---|
[QUADTREE] 쿼드 트리 뒤집기 (0) | 2022.01.14 |
[JOSEPHUS] 조세푸스 문제 (0) | 2022.01.09 |
[CCR] 문자 인식 (0) | 2022.01.09 |
[SPETIAL] Spatial Concepts Test (0) | 2022.01.09 |