UVALive6222 Unhappy Numbers【數學】(RE)
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
問題簡述:(略)
問題分析: 某一個正整數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;
}