Project Euler Homework
|
00001 00010 #include <iostream> 00011 00012 unsigned 00013 factor (unsigned *N, unsigned k0 = 3) //destructive, find smallest prime factor only 00014 { 00015 if (!(*N & 1)) { //multiple of 2 00016 *N >>= 1; //faster than *N/=2 00017 return 2; 00018 } 00019 00020 for (unsigned k = k0; k <= *N; k++) 00021 if (*N % k == 0) { 00022 *N /= k; 00023 return k; 00024 } 00025 return 1; 00026 } 00027 00028 unsigned 00029 term (unsigned p, unsigned k) //calculate p^0+p^1+...+p^k 00030 { 00031 unsigned t = 1; 00032 for (unsigned i = 1; i <= k; i++) { 00033 t = t * p + 1; 00034 } 00035 return t; 00036 } 00037 00038 //sum of all divisors of n except n 00039 //copied from 021.cpp 00040 unsigned 00041 sum_of_divisors (unsigned N) 00042 { 00043 unsigned answer = 1; 00044 00045 unsigned previous_prime = 2; //modified from 012.cpp 00046 unsigned power = 0; 00047 00048 unsigned r = N; 00049 unsigned div = 2; 00050 do { 00051 div = factor (&r, div); 00052 if (div == previous_prime) 00053 power++; 00054 else { //determined the power of the previous prime factor 00055 answer *= term (previous_prime, power); 00056 00057 previous_prime = div; 00058 power = 1; 00059 } 00060 //cout << div<<','<<answer<<' '; 00061 } while (div > 1); 00062 00063 answer -= N; //exclude N itself from the sum 00064 return answer; 00065 } 00066 00067 const unsigned max = 28123; 00068 00069 class abundant 00070 { 00071 bool array[max+1]; 00072 public: 00073 abundant() { 00074 for (unsigned i=0;i<12;i++) { 00075 array[i]=0; 00076 } 00077 for (unsigned i=12;i<=max;i++) { 00078 if (sum_of_divisors(i)>i) 00079 array[i]=1; 00080 else 00081 array[i]=0; 00082 } 00083 } 00084 unsigned search_back(unsigned x) { 00085 unsigned b; 00086 for (b=x-1;!array[b] && b>=12;b--); 00087 return b; 00088 } 00089 bool exist(unsigned x) { 00090 return array[x]; 00091 } 00092 }; 00093 00094 int main() 00095 { 00096 abundant abundant_nos; 00097 00098 unsigned long sum = 0; 00099 00100 //any numbers smaller than 24 cannot be expressed as a sum of two abundant numbers 00101 for (unsigned i=1;i<=23;i++) 00102 sum+=i; 00103 00104 for (unsigned i=24;i<=max;i++) { 00105 bool flag = 0; 00106 //search until b<12 00107 for (unsigned b=abundant_nos.search_back(i); 00108 b>=12;b=abundant_nos.search_back(b)) { 00109 //find a = i-b 00110 unsigned a=i-b; 00111 00112 //if i is the sum of a,b 00113 if (abundant_nos.exist(a)) { 00114 //std::cout << i << '=' << a<<'+'<<b<<std::endl; 00115 flag=1; 00116 break; 00117 } 00118 if (flag)break; 00119 } 00120 //i cannot be written as the sum of two abundant numbers. 00121 if (!flag) { 00122 //std::cout << i << ' '; 00123 sum+=i; 00124 } 00125 } 00126 00127 std::cout << sum << std::endl; 00128 00129 return 0; 00130 }