AtCoder Beginner Contest 112: D - Partition
問題
問題文
https://atcoder.jp/contests/abc112/tasks/abc112_d
問題概要
整数 N, M が与えられる.
各項の和が M となる 長さ N の数列 a のうち, a の最大公約数の最大値を求めよ.
解答例
指針
- M の約数を考える
解説
の最大公約数を とすると, 数列 の各項は の倍数となる.
各項が の倍数となり, 各項の和 も の倍数となるので以下のように書ける.
したがって, は の約数となることが分かる.
k を M の約数とする
- のとき
各項が k のとき和が M となる. このとき, a の最大公約数は k.
- のとき
必ず, k より小さい項が出てくるため, k は a の最大公約数とはなり得ない.
- のとき
k は Mの約数なので, M / k は整数となる. M / k = t とおくと条件より t > N が成り立つ.
となり, k は a の最大公約数となり得る.
以上のことから, M の約数 k のうち であるものが解の候補となり, その中で最大のものが解となることが分かる.
約数の列挙は片方を求めるとその数で除算することでもう一方がもとまるので でできる.
- C++ による実装例
// submission: https://atcoder.jp/contests/abc112/submissions/3873615 // Language: C++14 (GCC 5.4.1) // Time: 1 ms // Memoly: 256 KB #include <iostream> #include <algorithm> using namespace std; int main() { int N, M, ans = 0; cin >> N >> M; for (int k = 1; k*k <= M; k++) { if (M % k == 0) { if (k <= M / N) { ans = max(ans, k); } if ( (M / k) <= M / N) { ans = max(ans, M/k); } } } cout << ans << endl; return 0; }
- Python3 による実装例
#!/usr/bin/env python3 # submission: https://atcoder.jp/contests/abc112/submissions/3873634 # Language: Python3 (3.4.3) # Time: 24 ms # Memoly: 3060 KB from math import sqrt N, M = map(int, input().split()) ans = 0 for k in range(1, int(sqrt(M)) + 1): if M % k == 0: if k <= M / N: ans = max(ans, k) if M/k <= M/N: ans = max(ans, M//k) print(ans)