Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで4つのパラメータを持つ方程式の解となるペア(x, y)の個数を求めるプログラム

問題の概要

4つの整数 a、b、c、d が与えられたとき、次の方程式を満たすペア (x, y) の個数を求めます。

x² + y² = (x × a) + (y × b)

ただし、x の範囲は [1, c]、y の範囲は [1, d] とします。

たとえば、入力が a = 2、b = 3、c = 2、d = 4 の場合、出力は 1 になります。このとき条件を満たすのは (2, 3) のみです。実際、2² + 3² = 13 であり、(2 × 2) + (3 × 3) = 13 となるため、等式が成立していることが確認できます。

解法のアプローチ

この問題は、方程式を y についての二次方程式として変形することで効率的に解けます。式を整理すると、次のようになります。

y² − b·y + (x² − a·x) = 0

この二次方程式が整数解 y を持つかどうかは、判別式 D = b² − 4(x² − a·x) を調べることで判定できます。D が完全平方数であり、y = (b ± √D) / 2 が 1 以上 d 以下の整数になるとき、その y は有効な解となります。

アルゴリズムの手順

  • 答えを格納する変数 ans を 0 で初期化します。
  • x を 1 から c まで順に処理します。
    • l = x × (x − a) を計算します。
    • 判別式 det2 = b² − 4 × l を計算します。
    • det2 が 0 に等しく、b が偶数で、1 ≤ ⌊b / 2⌋ ≤ d を満たす場合は、ans を 1 増やして次の反復へ進みます(重解のケース)。
    • det2 が 0 より大きい場合は、以下を判定します。
      • det を det2 の平方根の整数部分とします。
      • det² が det2 に等しく、かつ (b + det) が偶数である場合:
        • 1 ≤ ⌊(b + det) / 2⌋ ≤ d ならば、ans を 1 増やします。
        • 1 ≤ ⌊(b − det) / 2⌋ ≤ d ならば、ans を 1 増やします。
  • 最後に ans を返します。

Pythonでの実装例

それでは、上記の手順を実際の Python コードで確認してみましょう。

def solve(a, b, c, d):
   ans = 0
   for x in range(1, c + 1):
      l = x * (x - a)

      det2 = b * b - 4 * l
      if det2 == 0 and b % 2 == 0 and 1 <= b // 2 <= d:
         ans += 1
         continue
      if det2 > 0:
         det = int(round(det2 ** 0.5))
         if det * det == det2 and (b + det) % 2 == 0:
            if 1 <= (b + det) // 2 <= d:
               ans += 1
            if 1 <= (b - det) // 2 <= d:
               ans += 1
   return ans

a = 2
b = 3
c = 2
d = 4
print(solve(a, b, c, d))

入力

2, 3, 2, 4

出力

1

計算量のポイント

このアルゴリズムは x の各値に対して定数時間の計算しか行わないため、全体の時間計算量は O(c) です。y の候補をすべて試す O(c × d) の素朴な全探索と比べ、d が大きいケースでも高速に動作するのが大きな利点です。二次方程式の判別式を活用することで、数学的な性質をそのままアルゴリズムに落とし込んだ美しい解法といえます。

  1. 【Python】ある数の最大の素因数を求めるプログラムの書き方

    この記事では、「与えられた整数の最大の素因数を求める」という問題に対する解決方法を、具体的なコード例とともにわかりやすく解説します。 問題文 正の整数 n が与えられたとき、その数の最大の素因数を求めます。 例えば n = 15 の場合、15 は 3 × 5 と素因数分解できるため、答えは 5 となります。 解き方のアプローチ 入力された数を、小さい約数から順番に割っていくことで素因数分解します。 割り切れるたびに、その時点での約数(素因数)を「最大値」として更新していきます。 平方根まで調べれば十分なため、計算量を抑えられます。 実装例(サンプルコード) import math def

  2. 【Python】与えられた数がフィボナッチ数かどうかを判定する方法を解説

    本記事では、以下の問題文に対する解決策について詳しく学んでいきます。 問題の定義 数値 n が与えられたとき、その数がフィボナッチ数であるかどうかを判定します。 ご存知のとおり、n番目のフィボナッチ数は「直前の2つのフィボナッチ数の和」として定義されます。しかし、この漸化式以外にも、フィボナッチ数には興味深い数学的な性質が存在します。 フィボナッチ数の判定に使える重要な性質 ある数 n がフィボナッチ数であるのは、次の条件が成り立つ場合、かつその場合に限られます。 5×n² + 4 が完全平方数である または 5×n² − 4 が完全平方数である つまり、上記のどちらか一方(または両方)が