Pythonで配列のペアの合計がkで割り切れるかどうかを確認するプログラム
問題概要
偶数個の要素を含む配列 nums と整数 k が与えられたとします。この配列をちょうど n/2 組のペアに分割し、それぞれのペアの合計が k で割り切れるようにできるかを判定するのが課題です。条件を満たす組み合わせが存在すれば True を、そうでなければ False を返します。
たとえば、nums = [9,5,3,4,7,10,20,8]、k = 3 の場合を考えてみましょう。(9, 3)、(5, 7)、(4, 20)、(8, 10) というペアを作ることができ、すべてのペアの合計が3で割り切れるため、出力は True になります。
解決手順
この問題は、各要素を「kで割った余り」の観点で扱うことで解けます。具体的には次の手順に従います。
- 空のリスト
dpと、初期値0のカウンターcountを用意します。 - 配列
numsの各要素xについて、以下を繰り返します。t = k - (x % k)を計算します。t == k(つまり x が k で割り切れる)の場合は、countを1増やします。- それ以外の場合は、
tをリストdpの末尾に追加します。
count % 2 != 0(kで割り切れる要素が奇数個)の場合はFalseを返します。これらの要素は互いにペアを組む必要があるためです。- リスト
dpを昇順にソートします。 - ポインタ
low = 0、high = len(dp) - 1を設定します。 low < highの間、以下を繰り返します。dp[low] + dp[high] != kであればFalseを返します。lowを1増やし、highを1減らします。
- すべてのペアが条件を満たしていれば
Trueを返します。
実装例
以下の実装を見ると、理解がより深まるでしょう。
def solve(nums, k): dp=[] count=0 for x in nums: t=k-(x % k) if t == k: count+=1 else: dp.append(t) if count % 2 != 0: return False dp.sort() low = 0 high = len(dp)-1 while low < high: if dp[low] + dp[high] != k: return False low += 1 high -= 1 return True nums = [9,5,3,4,7,10,20,8] k = 3 print(solve(nums, k))
入力
[9,5,3,4,7,10,20,8], 3
出力
True
アルゴリズムのポイント
要素 x と y の合計が k で割り切れるのは、(x mod k) + (y mod k) が k または 0 になるときと同じです。そこで、余りが0の要素は互いにペアを組めるため個数だけを数え、それ以外の要素については「k − 余り」という相方の値をリスト dp に記録します。ソート後、両端から中央へ向かって2つのポインタを動かしながら合計が k になるかを確認すれば、全要素が適切な相手と対応しているかを O(n log n) の計算量で効率的に検証できます。
-
Pythonで点が凸包を形成しているかどうかを判定する方法
多角形の外周にある頂点が時計回りの順序で与えられているとします。このとき、これらの点が凸包(コンベックスハル)を形成しているかどうかを判定する必要があります。 上の図からも分かるように、凸多角形では連続する3つの頂点からなる内角がすべて180°以下になります。つまり、すべての角度が180°以下であれば、その多角形は凸包であると判断できます。 例えば、入力が points = [(3,4), (4,7), (7,8), (11,6), (12,3), (10,1), (5,2)] のような場合、出力は True になります。 解法のアプローチ この問題を解くには、以下の手順に従います。 n
-
【Python】配列内のすべての桁を使って3で割り切れる数を作成できるか判定する方法
この記事では、与えられた問題文を解決するための解法とアプローチについて詳しく解説します。 問題文 整数の配列が入力として与えられたとき、これらの数値に含まれるすべての桁を使用して、3で割り切れる整数を作成できるかどうかを判定する必要があります。 ここでは、整数の配列と配列の長さという2つの引数を受け取る関数を作成します。 解法のポイント この実装は、暗算でよく使われる数学的な性質に基づいています。それは次の通りです。 「ある数の各桁の合計が3で割り切れるならば、その数自体も3で割り切れる」 この性質を利用すると、実際に桁を組み合わせて数値を生成する必要はなく、配列内の各要素について3で割った余