Algorithm, Data structure/Solved Algorithmic Problem

Project Euler #21 - Amicable numbers

JaykayChoi 2016. 6. 30. 23:30

Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n).
If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers.

For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.

Evaluate the sum of all the amicable numbers under 10000.



출처: https://projecteuler.net/problem=21


n의 약수들 중에서 자신을 제외한 것의 합을 d(n)이라 할 때, 서로 다른 두 정수 a, b에 대하여 d(a) = b 이고 d(b) = a 이면 

a, b는 amicable pair 이라 하고 a와 b를 각각 amicable numbers 이라 한다.

예를 들어 220의 proper divisors 는 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 이므로 d(220) = 284 이고, 

284의 proper divisors 는 1, 2, 4, 71, 142 이므로 d(284) = 220 입니다. 따라서 220과 284는 amicable pair 입니다.

10000 이하의 amicable numbers 을 모두 찾아서 그 합을 구하세요.


이 문제는 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110, 220 에서 2의 pair 라 할 수 있는 값이 110 이고, 4 -> 55, 5 -> 44 ... 인 점을 이용해 루트값까지만 계산을 하는 방법으로 시간 복잡도를 줄일 수 있습니다.



my solving

c++

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
#include <fstream>
#include <iostream>
#include <algorithm>
using namespace std;
 
 
int sumProperDivisors(int number) 
{
    int ret = 1;
    int sqrtn = sqrt(number);
    for (int i = 2; i <= sqrtn; i++)
    {
        if (number % i == 0
        {
            ret += i;
            int pairNum = number / i;
            if (pairNum != i)
                ret += pairNum;
        }
    }
    return ret;
}
 
int main() 
{
    int ret = 0;
    
    for (int i = 2; i <= 10000; i++
    {
        int sum = sumProperDivisors(i);
 
        if (i == sumProperDivisors(sum) && i != sum)
            ret += i;
    }
    cout << ret << endl;
    system("pause");
    return 0;
}
cs