Problem 92
A number chain is created by continuously adding the square of the digits in a number to form a new number until it has been seen before.
For example,
44 → 32 → 13 → 10 → 1 → 1
85 → 89 → 145 → 42 → 20 → 4 → 16 → 37 → 58 → 89
Therefore any chain that arrives at 1 or 89 will become stuck in an endless loop. What is most amazing is that EVERY starting number will eventually arrive at 1 or 89.
How many starting numbers below ten million will arrive at 89?
C++(Faster):
#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
const int MAXN = 10000000;
int arrive[MAXN], chainno[MAXN];
int no;
int nextval(int n)
{
int sum, v;
sum = 0;
while(n) {
v = n % 10;
sum += v * v;
n /= 10;
}
return sum;
}
void makechain(int n)
{
no++;
while(n != 1 && n != 89) {
if(chainno[n] > 0) {
n = arrive[chainno[n]];
break;
}
chainno[n] = no;
n = nextval(n);
}
arrive[no] = n;
}
int main()
{
int n;
while(cin >> n && n <= MAXN) {
memset(arrive, 0, sizeof(arrive));
memset(chainno, 0, sizeof(chainno));
chainno[1] = 1;
arrive[1] = 1;
chainno[89] = 2;
arrive[2] = 89;
no = 2;
for(int i=1; i<n; i++)
if(i != 1 && i != 89)
makechain(i);
int count = 0;
for(int i=1; i<n; i++)
if(arrive[chainno[i]] == 89)
count++;
cout << count << endl;
}
return 0;
}
C++:
#include <iostream>
#include <cstring>
#include <stack>
using namespace std;
const int MAXN = 10000000;
int arrive[MAXN];
int nextval(int n)
{
int sum, v;
sum = 0;
while(n) {
v = n % 10;
sum += v * v;
n /= 10;
}
return sum;
}
void makechain(int n)
{
stack<int> s;
while(n != 1 && n != 89) {
if(arrive[n] > 0) {
n = arrive[n];
break;
}
s.push(n);
n = nextval(n);
}
while(!s.empty()) {
int val = s.top();
s.pop();
arrive[val] = n;
}
}
int main()
{
int n;
while(cin >> n && n <= MAXN) {
memset(arrive, 0, sizeof(arrive));
arrive[1] = 1;
arrive[89] = 89;
for(int i=1; i<n; i++)
makechain(i);
int count = 0;
for(int i=1; i<n; i++)
if(arrive[i] == 89)
count++;
cout << count << endl;
}
return 0;
}