AtCoder NoviStepsを埋めてみる(10) 素数判定・約数列挙・素因数分解の続きです。今回は整数系探索問題です。

B – Around Square

B – Around Square

問題の概要

N 以下の平方数のうち、最大のものを求めよ。

1 から N まで全探索して i^2 が N 以下である i の最大値を探せばよいです。

全探索ではなく計算で答えを出してもよいです。√N の整数部分を二乗すれば解が得られます。Math.Sqrt(N) は double 型を返しますが、double 型の精度は 10進数では約 15 桁なので N が大きな値の場合は注意が必要です(この問題は N ≦ 10^9 なので問題ない)。

C – Digits in Multiplication

C – Digits in Multiplication

問題の概要

整数 N が与えられる。
F(A, B) を「正整数 A, B を 10 進表記したときの大きい方の桁数」と定義する。
例:F(3, 11) なら 2。
(A, B) が N = A × B を満たすように動くとき、F(A, B) の最小値を求めよ。

A × B = N となる A, B を全探索するのですが、A ≦ B という条件をつければ O(√N) で全探索できます。

A – Sum and Product

A – Sum and Product

問題の概要

整数 S, P が与えられる。
N + M = S, N × M = P を満たすような正の整数の組 (N, M) は存在するだろうか?

N, M を全探索します。N + M = S に対して N × M = P となる N, M は限られているので N × M = P(N ≦ M)であるペアを求め、これが N + M = S であるか確認して条件を満たしているなら “Yes” を出力します。

092 – Beautiful Rectangle

092 – Beautiful Rectangle

問題の概要

縦の長さと横の長さが整数である面積 N の長方形について、周の長さの最小値を求めよ。

a, b (a ≦ b) を全探索して a × b = N となるものを探します。a, b は長方形の縦横の長さなので周の長さであれば和を 2 倍すればよいです。そこから最小値を探します。

C – Minimize Abs 2

C – Minimize Abs 2

問題の概要

正整数 D が与えられる。
非負整数 x, y に対する |x^2 + y^2 – D| の最小値を求めよ。

|x^2 + y^2 – D| を最小化するのであれば、できるだけ x^2 + y^2 を D に近づければよいです。x を 0 から √D まで全探索します。

仮の x の値を決め打ちして、D – x * x – y * y <= 0 である最小の y を二分探索法で取得します。このとき D - x * x - y * y の値は 0 以下の値になりますが、実はそれよりも少し大きい正の値のほうが適切だったという場合もあるので D - x * x - (y - 1) * (y - 1) の場合(ただし y - 1 ≧ 0)も調べます。これらの結果から絶対値を調べて最小になるものを解として出力します。 二分探索ではライブラリ ac-library-csharp の StlFunction.BinarySearch を使っています。 参考: ac-library-csharpを使ってみる

C – Four Variables

C – Four Variables

問題の概要

正整数 N が与えられる。
正整数の組 (A, B, C, D) であって、A × B + C × D = N を満たすものの個数を求めよ。

正整数の組 (A, B, C, D) を全探索するのは無理があります。しかし A × B ≦ N となる正整数の組 (A, B) であれば全探索可能です。C × D ≦ N となる正整数の組 (C, D) は内容的に前者とまったく同じです。

なので前者のそれぞれに対してこれに加算することで N になるものがあるか後者のなかから探します。そしてこれを数え上げます。

C – Unexpressed

C – Unexpressed

問題の概要

整数 N が与えられる。
1 以上 N 以下の整数のうち、2 以上の整数 a, b を用いて a^b と表せないものはいくつあるだろうか?

N から 2 以上の整数 a, b を用いて a^b と表せるものの個数を引けばよいです。a の探索範囲は 2 以上 √N 以下です。b の探索範囲は 2 以上で a^b ≦ N を満たすものです。

C – Remainder Minimization 2019

C – Remainder Minimization 2019

問題の概要

非負整数 L, R が与えられる。
2 つの整数 i, j を L ≦ i < j ≦ R を満たすように選ぶ。
(i × j) mod 2019 の最小値を求めよ。

(i × j) mod 2019 = (i mod 2019 × j mod 2019) mod 2019 です。なので L ≦ i < j ≦ R ではなく L ≦ i < j ≦ Math.Min(R, L + 2019) の範囲で i, j を全探索すればよいです。

B – □□□□□

B – □□□□□

問題の概要

一辺の長さが 1 の正方形のタイルが n 枚ある。
これらのタイルのうちいくつかを重ならないように隙間なく並べて大きな長方形を作りたい。
出来上がる長方形はできるだけ正方形に近いほうがよいが、使わずに余るタイルの枚数もできるだけ少なくしたい。
(長方形の縦と横の長さの差の絶対値 + 余ったタイルの枚数)の最小値を求めよ。

a × b ≦ N (a ≦ b) となる a, b を全探索して(長方形の縦と横の長さの差の絶対値 + 余ったタイルの枚数)の最小値を求めます。

C – Max GCD 2

C – Max GCD 2

問題の概要

整数 A, B が与えられる。
整数 x, y を A ≦ x < y ≦ B となるように選ぶときの gcd(x, y) の最大値を求めよ。

x, y を全探索するより、z は公約数になりうるかを考えたほうが速いです。z としてありえる値は B 未満です。

z の倍数が A 以上 B 以下の区間に複数存在するなら z は公約数になりえる数です。

C – XYZ Triplets

C – XYZ Triplets

問題の概要

f(n) を以下の 2 つの条件の両方を満たすような 3 つの整数の組 (x, y, z) の個数と定義する。
x, y, z は自然数
x^2 + y^2 + z^2 + xy + yz + zx = n
整数 N が与えられるので f(1), f(2), f(3), …, f(N) をそれぞれ求めよ。

x, y, z を全探索するのですが、二乗があるのと正整数同士の足し算なので探索範囲は √N まででよいです。

C – 2026

C – 2026

問題の概要

正整数 n が次の条件を満たす時、n を 良い整数 と呼ぶことにする。
0 < x < y かつ x^2 + y^2 = n を満たす整数の組 (x, y) がただ 1 つ存在する。
正整数 N が与えられる。
N 以下の良い整数をすべて列挙せよ。

二乗があることと正整数同士の足し算なので x, y の探索範囲は √N までです。それぞれの(x, y) で x^2 + y^2 を計算し、ひとつの整数組でしか得られなかった整数が良い整数なので、それを出力します。

D – Square Permutation

D – Square Permutation

問題の概要

数字のみからなる、長さ N の文字列 S が与えられる。
S を並べ替えてできる文字列を十進法の整数として解釈したもののうち、平方数であるようなものがいくつあるか求めよ。

平方数を先につくって、S を並べ替えてこれらと一致させられるかを考えます。一致させられるかどうかは両者をソートして各要素がすべて一致するかを調べればいいのですが、先頭に 0 を付加することで一致するケースもあるので S のほうが長い場合は ‘0’ を追加して長さを同じにしてから一致判定をしています。

D – Happy New Year 2023

D – Happy New Year 2023

問題の概要

正整数 N が与えられる。
N は 2 つの相異なる素数 p, q を用いて N = p^2 × q と表せることがわかっている。
p, q を求めよ。

N の最大値が 9 × 10^18 であることと、探す素数のペアが N = p^2 × q を満たすものであることから 10^7 以下の素数をすべて求めます。そのための処理にエラトステネスの篩を使っています。そのためのメソッドである GetPrimes メソッドはここで定義 しています。

最初に N を割り切ることができる p^2 を探します。見つかったら N / (p * p) が q です。見つからなかった場合は p は 10^7 を超える大きな素数です。この場合は q は小さい素数になるので N を割り切ることができる q を探します。見つかった場合は N / q の平方根が p となります。

D – I hate Factorization

D – I hate Factorization

問題の概要

A^5 – B^5 = X を満たす整数の組 (A, B) をひとつ示せ。
ただし解は必ず存在することが保証されている。

A と B の探索範囲がどうなるのかがこの問題の肝です。(A + 1)^5 – A^5 > X となるのであれば、それよりも大きな値のなかから A, B を探そうとしても絶対に見つかりません。実験してみると Math.Pow(10, 9) < Math.Pow(120, 5) – Math.Pow(119, 5) であることがわかり、(A, B) の探索範囲も絶対値が 120 まででよいことがわかります。

fermat – フェルマー方程式 (Fermat)

fermat – フェルマー方程式 (Fermat)

素数 P と自然数 N が与えられる。
x^N + y^N ≡ z^N (mod P) をみたす整数 x, y, z (0 ≦ x, y, z ≦ P – 1) の組 (x, y, z) の個数を求めよ。

最初に x^N % P を計算しておきます。x の範囲は 0 以上 P 未満です。mod P を考えるのでそれより大きな数で考えるのは無駄です。あとは 0 ≦ a, b ≦ P – 1 を全探索します。

x^N % P == a で y^N % P == b のとき z^N == (a + b) % P になるのでそのような場合がそれぞれ何通りあるのかを足し合わせていけば解を得ることができます。