Project Euler Homework
|
00001 00009 #include <iostream> 00010 using namespace std; 00011 00012 /* Find smallest prime factor*/ 00013 unsigned 00014 factor (unsigned *N, unsigned k0 = 3) 00015 { 00016 if (!(*N & 1)) //multiple of 2 00017 { 00018 *N >>= 1; //faster than *N/=2 00019 return 2; 00020 } 00021 00022 for (unsigned k = k0; k <= *N; k++) 00023 if (*N % k == 0) 00024 { 00025 *N /= k; 00026 return k; 00027 } 00028 return 1; 00029 } 00030 00031 /*calculate p^0+p^1+...+p^k*/ 00032 unsigned 00033 term (unsigned p, unsigned k) 00034 { 00035 unsigned t = 1; 00036 for (unsigned i = 1; i <= k; i++) 00037 { 00038 t = t * p + 1; 00039 } 00040 return t; 00041 } 00042 00043 /* sum of all divisors of n except n */ 00044 unsigned 00045 d (unsigned N) 00046 { 00047 unsigned answer = 1; 00048 00049 unsigned previous_prime = 2; //modified from 012.cpp 00050 unsigned power = 0; 00051 00052 unsigned r = N; 00053 unsigned div = 2; 00054 do 00055 { 00056 div = factor (&r, div); 00057 if (div == previous_prime) 00058 power++; 00059 else //determined the power of the previous prime factor 00060 { 00061 answer *= term (previous_prime, power); 00062 00063 previous_prime = div; 00064 power = 1; 00065 } 00066 //cout << div<<','<<answer<<' '; 00067 } 00068 while (div > 1); 00069 00070 answer -= N; //exclude N itself from the sum 00071 return answer; 00072 } 00073 00074 /*memorize impossible integers*/ 00075 class lookup_table 00076 { 00077 bool x[10000]; 00078 public: 00079 lookup_table () 00080 { 00081 bool *p = x; 00082 for (unsigned i = 0; i < 10000; i++, p++) 00083 *p = 0; 00084 } 00085 bool exception (unsigned k) 00086 { 00087 return x[k]; 00088 } 00089 void push (unsigned k) 00090 { 00091 x[k] = 1; 00092 } 00093 }; 00094 00095 int 00096 main () 00097 { 00098 00099 unsigned Sum = 0; 00100 lookup_table table; 00101 00102 for (unsigned a = 3; a < 10000; a++) 00103 { 00104 if (table.exception (a)) 00105 continue; 00106 unsigned b = d (a); 00107 if (b == a || b >= 10000) 00108 continue; 00109 if (d (b) == a) 00110 { 00111 Sum += a + b; 00112 table.push (b); //so b will never appear again 00113 //cout << a << ' '<<b << ' '; 00114 } 00115 else if (b > a && b < 10000) //add an exception to reduce computation time 00116 table.push (b); 00117 } 00118 00119 cout << Sum << endl; 00120 return 0; 00121 } 00122