競技プログラミング用 知識集積所
ABC439B - Happy Number
最終更新:
sport_programming
-
view
問題
必要知識
A問題レベルのものは省略
考え方
基本的には、whileループで1回ずつ操作を行って、毎回結果が1であるかどうかを確認すればよいだけ。
問題は2点。
1つめは、この操作1回をどうやって書くか。
まず桁ごとに数を取り出す必要があるが、これはint型の「全ての桁を1つずつ抽出」を参照。
取り出した数値をそれぞれ2乗して、0で初期化した変数に足しこんでいけばよい。
関数定義※で切り出してもいいし、どうせコードの1ヶ所でしか使わないのでwhileループ内にベタ書きしてもいい。
1つめは、この操作1回をどうやって書くか。
まず桁ごとに数を取り出す必要があるが、これはint型の「全ての桁を1つずつ抽出」を参照。
取り出した数値をそれぞれ2乗して、0で初期化した変数に足しこんでいけばよい。
関数定義※で切り出してもいいし、どうせコードの1ヶ所でしか使わないのでwhileループ内にベタ書きしてもいい。
2つめは、1に絶対にならないケースの検出。
このように前の数値1つだけから次の数値が決まる数列は、必ず以下のいずれかになる。
このように前の数値1つだけから次の数値が決まる数列は、必ず以下のいずれかになる。
- 値がループする
- 二度と同じ値が出てこないまま発散する
しかし今回は10000以下の数からは必ず9*9*4=324以下にしかならないので、発散は絶対にしない。
つまり今回は必ずループするオチになり、1が出てこないというのは、ループが起こった時点で1が一度も出現していないことを意味する。
ということで、set※を利用して今まで一度でも出てきた数の一覧を作り、都度「今できた数が出現済の数かどうか?」をチェックすればよい。
いずれ出現済のものが必ず出現し、そのときに1が未出現なら"No"と答えればよい。
つまり今回は必ずループするオチになり、1が出てこないというのは、ループが起こった時点で1が一度も出現していないことを意味する。
ということで、set※を利用して今まで一度でも出てきた数の一覧を作り、都度「今できた数が出現済の数かどうか?」をチェックすればよい。
いずれ出現済のものが必ず出現し、そのときに1が未出現なら"No"と答えればよい。
解答例
注意点
1という入力に注意。
入力が1だった場合に、「計算結果の1は既出だからNo」とならないように注意。
1かどうかの判定を先にやるなどで対処する。
1かどうかの判定を先にやるなどで対処する。