Project Euler에 있는 재미있는 문제를 하나 풀었습니다.
6번째 문제로 제목은 Sum square difference 입니다.
The sum of the squares of the first ten natural numbers is,
12 + 22 + ... + 102 = 385
The square of the sum of the first ten natural numbers is,
(1 + 2 + ... + 10)2 = 552 = 3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is 3025 385 = 2640.
Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
1부터 100까지 각 숫자의 제곱의 합에서 1부터 100까지 더한 수의 제곱을 빼면 얼마인지 묻는 문제입니다.
일단 무식하게 for문을 돌려서 각 제곱의 합을 구하고,
또한 매 루프마다 더한 sum을 제곱하면 될 것 같습니다.
하지만 100까지가 아니라 더 큰 수까지의 값을 구하라고 하면 integer의 범위를 넘어가 버리기 때문에 다른 방법이 필요합니다.
그리고 알고리즘 문제니까 뭔가 속도도 빠르게 할 수 있는 방법이 있을 것입니다.
저는 이렇게 풀어 보았습니다.
(a+b) = a2 + b2 + 2ab 이므로,
이렇게 됩니다.
각 숫자의 제곱 부분을 좌항으로 옮기면 남는 부분이 결국 우리가 구하고자 하는 값입니다.
각 부분에 포함된 2를 앞으로 묶어 내면 뭔가 규칙이 생기네요.
n=3 일 때는 2번의 덧셈, n=4일 때는 3번의 덧셈이 됩니다.
즉 n-1번 loop를 돌리면 될 것 같습니다.
그리고 각 항에서 곱셈으로 연결된 좌측 숫자는 n-1에서 1까지 작아지고,
우측 숫자는 (좌측 숫자+1)부터 n까지 더한 값입니다.
이를 구현하면 이렇게 됩니다.
public int sumSquareDifference(int n) {
if (n < 1) {
return -1;
}
int sum = 0;
for (int i = n - 1; i > 0; i--) {
int _sum = 0;
for (int j = i + 1; j <= n; j++) {
_sum += j;
}
sum += 2 * (i * _sum); } return sum; }
정답!!
하지만 이 알고리즘의 성능은 O(n2)으로 그다지 좋지 않습니다.
Project Euler에서 제시한 정답은 단 3줄의 코딩으로 끝납니다.
성능은 O(1)입니다. loop를 쓰지도 않았다는 말입니다.
여러분도 정답을 보기 전에 다른 방법으로 한 번 풀어보시길 바랍니다. 풀이를 보면 아하! 하고 느끼실 수 있을 겁니다.
평소 문제를 접할 때에도 바로 컴퓨터 앞에서 키보드를 두들기기 전에 좀더 간단한 문제로 바꿀 수 있는 방법을 고민해 보세요.
만약 성공한다면 메모리와 수행 시간을 획기적으로 줄일 수 있을 겁니다.
'Programming을 배우자' 카테고리의 다른 글
[펌] [B급 프로그래머] 하루 안에 배울 수 있는 몇 가지 유용한 (컴퓨터) 기술이 무엇일까요? (0) | 2012.12.17 |
---|---|
Project Euler - 수학문제를 Programming 알고리즘으로 풀어보는 사이트 (0) | 2011.05.09 |