B - Happy Number 解説 by en_translator
Original proposer: admin
First, implement a function \(f(n)\) that accepts an integer \(n\) and returns the result of one operation.
There are several ways to decompose the integer \(n\) into digits:
- Inspect the remainder when \(n\) is divided by \(10\), and then divide \(n\) by \(10\), rounded down to an integer. Repeat this until \(n\) becomes \(0\).
- Interpret \(n\) as a string, and extract the digits.
Now suppose that \(f(n)\) has been implemented.
The problem can be inspected in either way:
- Repeatedly replace \(n\) with \(f(n)\). If you arrive at \(1\), the answer is
Yes; otherwise, if you return to the same value, determine that the answer isNo. - Replace \(n\) with \(f(n)\) repeatedly a sufficient number of times (for example, \(1000\) times). Check if the result is \(1\).
The proof is a bit difficult, so we will present sample code first. This is an implementation of the former approach.
Sample code (C++):
#include<bits/stdc++.h>
using namespace std;
int f(int n){
string s=to_string(n);
int res=0;
for(auto &nx : s){
res+=(nx-'0')*(nx-'0');
}
return res;
}
int main(){
int n;
cin >> n;
set<int> history;
while(n>1){
if(history.find(n)!=history.end()){
cout << "No\n";
return 0;
}
history.insert(n);
n=f(n);
}
cout << "Yes\n";
return 0;
}
Bonus: in fact, happy numbers are so famous concept that Wikipedia has an article about it. You can even find and use a code snippet online.
We will now justify the solution in the problem statement.
By the constraints, \(1 \le N \le 2026\), so the given \(N\) has at most \(4\) digits.
Then \(f(N) \le 9^2+9^2+9^2+9^2 = 324\), which means that \(f(N)\) has \(3\) digits.
This implies that the result of applying the operation twice \(f(f(N)) \le 9^2+9^2+9^2 = 243\).
Moreover, we can also see that any integer \(y\) up to \(243\) satisfies \(f(y) \le 243\); that is, applying the operation to an integer up to \(243\) always result in another integer up to \(243\).
Also, once we return to an already-visited integer without reaching \(1\), we are indefinitely trapped in the loop and never reach \(1\).
With the fact that once you reach an integer \(y\) less than or equal to \(243\), it never becomes greater than \(243\), we see that if you apply the operation \(243\) times to \(y\), the resulting integer is always a visited integer.
If you have reached \(1\) at least once, then \(f(1)=1\), so you should be trapped in \(1\); conversely, if you have not reached \(1\) after a sufficient number of iterations, it turns out that you are trapped in a loop that does not contain a \(1\).
Thus, we can see that the necessary number of iterations is at most about \(300\). With an appropriate implementation, the problem can be answered without reporting a wrong answer nor exceeding the time limit.
投稿日時:
最終更新: