zuka
ABCをコツコツ解いていきます。
本記事は,管理人の競技プロ精進日記としてログを取ったものです。モチベーションを爆上げするために,積極的にアウトプットしていく作戦です。これから競技プログラミングを始めようと考えている人や,なんとなく敷居が高いと感じている人の参考になれば嬉しく思います。その他の記事は以下をご覧ください。
目次
本記事の概要
Atcoderで初心者用のコンテストとして開催されているAtcoder Beginner Contest(通称ABC)を解いていくものです。今回はABC144-C「Walk on Multiplication Table」です。
ポイント
良問です。$N \leq 10^{12}$なので,$i \times j = N$となる全ての$i$に対して全探索を用いると,$O(N)$となり間に合いません。そこで,$i$を探す範囲を狭めます。
いま,$i$が$\sqrt{N}$よりも大きければ,$i \times j = N$を満たす整数$j$は見つかりません。ですので,$i$を探す範囲は$1 \leq \sqrt{N}$でOKです。こうすれば,計算量は$O(\sqrt{N})=O(10^6)$となり十分間に合います。
おさえるべき内容
全探索の範囲を狭める
実装
#include <bits/stdc++.h>
#define _GLIBCXX_DEBUG
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define repi(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
using namespace std;
int main(){
long long N, Q, R;
// 初期値はとりあえずNの最大値としておく
long long ans = pow(10, 12) + 1;
cin >> N;
rep(i, sqrt(N)+1){
// i+1がNの約数であるかを判断する
Q = N / (i+1);
R = N % (i+1);
// もしNの約数であれば,その因数を足し算したものの最小値を保存する
if (R == 0) ans = min(ans, i + Q - 1);
}
cout << ans << endl;
}
コメント