Project Euler Homework

023.cpp

Go to the documentation of this file.
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 }
 All Classes Files Functions Variables