けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

AtCoder ABC 057 C - Digits in Multiplication (緑色, 300 点)

整数に関する問題でまずは直面する典型的な事柄を学べる教育的問題!!

例えば整数  n が素数かどうかを判定するのは、実は  2 から  \sqrt{n} まで順に試し割りすればよいという話など。

ただ、現代の ABC なら灰色 diff になりそうである。

問題へのリンク

問題概要

正の整数  N が与えられる。 N = A \times B を満たす正の整数  A, B の組をすべて考えたときの、「 A の桁数と  B の桁数のうちの最大値」の最小値を求めよ。

制約

  •  1 \le N \le 10^{10}

考えたこと

 N = A \times B を満たすような  (A, B) を全探索すれば OK!!!!!

そしてそれは、基本的には  N の約数をすべて求めてください、というのとほとんど同じ問題。実は

  •  A = 1, 2, \dots, \sqrt{N} まで考えて
  •  N %  A == 0 であれば
  •  B = \frac{N}{B} として、 (A, B) が候補になる

という感じ。なぜ  A \le \sqrt{N} までで良いか?それは、 A B との間に暗黙の大小関係として  A \le B が成立していると考えても差し支えない。そうすると  A \gt \sqrt{N} とすると  A \times B \gt N となるので矛盾する。

#include <iostream>
using namespace std;
const long long INF = 1LL<<60;

int calc_digit(long long n) {
    int res = 0;
    while (n > 0) {
        ++res;
        n /= 10;
    }
    return res;
}

int main() {
    long long N; cin >> N;
    long long res = INF;
    for (long long a = 1; a * a <= N; ++a) {
        if (N % a != 0) continue;
        long long b = N/a;
        long long tmp = max(calc_digit(a), calc_digit(b));
        res = min(res, tmp);
    }
    cout << res << endl;
}