Numbers have feelings too! For any positive integer, take the sum of the squares of each of its digits, and add them together. Take the result, and do it again. A number is Happy if, after repeating this process a finite number of times, the sum is 1. Some happy numbers take more iterations of this process to get to 1 than others, and that would be referred to as its distance from happiness. 1’s distance from happiness is 0. 23’s distance from happiness is 3, since 2^2 + 3^2 = 13, 1^2 + 3^2 = 10, and 1^2 + 0^2 = 1. Numbers are Unhappy if they are infinitely far away from happiness because they get stuck in a loop.
Given the lower end and upper end of a range of integers, determine how many Unhappy numbers are in that range (inclusive).
Input
There will be several test cases in the input. Each test case will consist of two positive integers, lo and hi (0 < lo ≤ hi ≤ 1018) on a single line, with a single space between them. Input will terminate with two ‘0’s.
Output
For each test case, output a single integer on its own line, indicating the count of Unhappy Numbers between lo and hi (inclusive). Output no extra spaces, and do not separate answers with blank lines.
Sample Input
1 10
1 100
0 0
Sample Output
7
80
Regionals 2012 >> North America - Southeast USA
问题链接:UVALive6222 Unhappy Numbers
问题简述:(略)
问题分析: 某一个正整数n,对其各位数字分别平方再求和得到一个新数,重复同样的计算,最终和变成1,则称n为快乐数;如果出现循环变不成1则不是快乐数。
程序说明:
使用set来判重复是一个好做法。
函数ishn()用来判定一个数是否是快乐数。
题记:(略)
RE的C++语言程序如下:
/* UVALive6222 Unhappy Numbers */
#include <bits/stdc++.h>
using namespace std;
const int N = 9 * 9 * 18;
const int N2 = 1e6;
int hn[N + 1];
int prefixsum[N2 + 1];
int ishn(int n) {
set<int> s;
while (n != 1) {
int sum = 0;
while (n) {
int d = n % 10;
sum += d * d;
n /= 10;
}
n = sum;
if (s.count(n))
break;
else
s.insert(n);
}
return n == 1;
}
int isHN(unsigned long long n)
{
if(n > N) {
int sum = 0;
while (n) {
int d = n % 10;
sum += d * d;
n /= 10;
}
return hn[sum];
} else
return hn[n];
}
void maketable()
{
for(int i = 1; i <= N; i++)
hn[i] = ishn(i);
prefixsum[0] = 0;
for(int i = 1; i <= N2; i++)
if(isHN(i))
prefixsum[i] = prefixsum[i - 1];
else
prefixsum[i] = prefixsum[i - 1] + 1;
}
int main()
{
unsigned long long lo, hi;
maketable();
while(~scanf("%lld%lld", &lo, &hi) && (lo || hi)) {
int cnt = 0;
// for(long long i = lo; i <= hi; i++)
// if(!isHN(i))
// cnt++;
if(hi <= N2) {
cnt = prefixsum[hi] - prefixsum[lo - 1];
} else if(lo < N2) {
cnt = prefixsum[N2] - prefixsum[lo - 1];
for(unsigned long long i = N2 + 1; i <= hi; i++)
if(!isHN(i))
cnt++;
} else {
for(unsigned long long i = lo + 1; i <= hi; i++)
if(!isHN(i))
cnt++;
}
printf("%d\n", cnt);
}
return 0;
}