Programming을 배우자

ProjectEuler 풀이 - Problem 6. Sum square difference

dextto™ 2013. 6. 11. 06:21


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를 쓰지도 않았다는 말입니다.


여러분도 정답을 보기 전에 다른 방법으로 한 번 풀어보시길 바랍니다. 풀이를 보면 아하! 하고 느끼실 수 있을 겁니다.


평소 문제를 접할 때에도 바로 컴퓨터 앞에서 키보드를 두들기기 전에 좀더 간단한 문제로 바꿀 수 있는 방법을 고민해 보세요.

만약 성공한다면 메모리와 수행 시간을 획기적으로 줄일 수 있을 겁니다.

반응형