The number 145 is well known for the property that the sum of the factorial of its digits is equal to 145: 1! + 4! + 5! = 1 + 24 + 120 = 145 Perhaps less well known is 169, in that it produces the longest chain of numbers that link back to 169; it turns out that there are only three such loops that exist: 169 → 363601 → 1454 → 169 871 → 45361 → 871 872 → 45362 → 872 It is not difficult to prove that EVERY starting number will eventually get stuck in a loop. For example, 69 → 363600 → 1454 → 169 → 363601 (→ 1454) 78 → 45360 → 871 → 45361 (→ 871) 540 → 145 (→ 145) Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms. How many chains, with a starting number below one million, contain exactly sixty non-repeating terms?
This problem is easy to implement and my implementation is almost brute-force, except using MAP to cache all the pair of number and the sum of the factorial of its digits.
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 | #include<iostream> #include<map> using namespace std; const int N=1e6; bool chain_of_length_60(int x); int sum_digit_factorial(int x); int fac(int i); int factorial(int n); int main() { int res=0; for (int i=70; i<N; i++) if (chain_of_length_60(i)) res++; cout << "Answer of Problem 74 is: " << res << endl; return 0; } bool chain_of_length_60(int x) { static map<int, int> mem; int sz = 61; int val, vals[sz]; int length=1; bool flag = false; vals[0] = x; int y = x; for (int i=1; i <= sz; i++) { if (mem.find(y) == mem.end() ) { val = sum_digit_factorial(y); mem[y] = val; } else { val = mem[y]; } y = val; for (int j=0; j<i; j++) { if (val == vals[j]) { flag = true; break; } } if (flag) break; vals[i] = val; length++; } return length == 60; } int sum_digit_factorial(int x) { int res = 0; while (x) { res += fac(x % 10); x = x / 10; } return res; } int fac(int i) { static int fac_mem[10]; if (i < 0 || i > 9) return NULL; if (!fac_mem[i]) { fac_mem[i] = factorial(i); } return fac_mem[i]; } int factorial(int n) { if (n <= 1) return 1; else n = n * factorial(n-1); return n; } |
> system.time(system("./pe74")) Answer of Problem 74 is: 402 user system elapsed 67.832 0.108 67.980