-
Notifications
You must be signed in to change notification settings - Fork 0
/
Project Euler #23.cpp
97 lines (81 loc) · 2.31 KB
/
Project Euler #23.cpp
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <iostream>
#include <set>
// constant according to problem statement
const unsigned int EverythingsASumFromHere = 28124;
// will contain all abundant numbers
std::set<unsigned int> abundant;
// generate sum of all divisor's of x
unsigned int getSum(unsigned int x)
{
// note: code very similar to problem 21
// find all factors:
// look only for the "smaller" divisors <= sqrt(x)
// and they have a "bigger" brother x / divisor
// 1 is always a divisor, but not the number x itself
unsigned int divisorSum = 1;
// therefore start at 2
for (unsigned int divisor = 2; divisor * divisor <= x; divisor++)
if (x % divisor == 0)
{
divisorSum += divisor;
// add the "bigger brother"
unsigned int otherDivisor = x / divisor;
// except square numbers
if (otherDivisor != divisor)
divisorSum += otherDivisor;
}
return divisorSum;
}
// return true if parameter can be written as the sum of two abundant numbers
bool isAbundantSum(unsigned int x)
{
// big numbers are always an abundant sum
if (x >= EverythingsASumFromHere)
return true;
// look at all small abundant numbers in ascending order
for (auto i : abundant)
{
// abort if there is no sum possible
if (i >= x) // or even faster: if (i > x/2)
return false;
// is its partner abundant, too ?
unsigned int other = x - i;
if (abundant.count(other) == 0)
continue;
// yes, we found a valid combination
return true;
}
// nope
return false;
}
int main()
{
// precomputation step:
// find all abundant numbers <= 28123
for (unsigned int i = 1; i < EverythingsASumFromHere; i++) // actually, we could start at 12
// divisor's sum bigger than the number itself ?
if (getSum(i) > i)
abundant.insert(i);
//#define ORIGINAL
#ifdef ORIGINAL
unsigned long long sum = 0;
for (unsigned int i = 0; i < EverythingsASumFromHere; i++)
{
// sum of all numbers which cannot be written as an abundant sum
if (!isAbundantSum(i))
sum += i;
}
std::cout << sum << std::endl;
#else
unsigned int tests;
std::cin >> tests;
while (tests--)
{
// find out whether a certain number can be written as an abundant sum
unsigned int x;
std::cin >> x;
std::cout << (isAbundantSum(x) ? "YES" : "NO") << std::endl;
}
#endif
return 0;
}