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

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

AtCoder ABC 144 C - Walk on Multiplication Table (灰色, 300 点)

約数列挙!!!

問題へのリンク

問題概要

正の整数  N が与えられる。
 a \times b = N を満たすような正の整数  (a, b) の組をすべて考えたときの、 a + b - 2 の最小値を求めよ。

制約

  •  2 \le N \le 10^{12}

考えたこと

これはまさに約数列挙の問題!!!
以下の記事の「3. 約数列挙」のところで、本質的に同じ問題の解説を行なっている。

qiita.com

具体的には次のようにすればよい。

  •  a = 1, 2, \dots と割っていく (ただし、 a \times a \le N の範囲まででよい)
  •  N a を割り切るとき、 b = \frac{N}{a} とする
  • そのような  a + b - 2 の最小値を求める

基本的には試し割りしていく全探索解法だが、 a \times a \le N の範囲でよい、というのがポイントになる。計算量は  O(\sqrt{N})

コード

#include <bits/stdc++.h>
using namespace std;

int main() {
    long long N;
    cin >> N;
    long long res = N + 1 - 2; // (a, b) = (1, N)
    for (long long a = 1; a * a <= N; ++a) {
        if (N % a == 0) res = min(res, a + N/a - 2);
    }
    cout << res << endl;
}