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

Pythonでカップとソーサーを棚にきれいに配置できるか判定する方法

3種類のカップが配列 p に、ソーサーが配列 q に入っており、利用できる棚の数 m が与えられているとします。このとき、カップとソーサーを「きれいに」配置できるかどうかを判定するのが本記事のテーマです。

「きれいな配置」となるための条件

カップとソーサーの配置が整然としていると言えるのは、次の3つの条件をすべて満たす場合です。

  • どの棚にも、カップとソーサーを混在させて置くことはできない
  • 1つの棚に置けるカップは最大5個まで
  • 1つの棚に置けるソーサーは最大10枚まで

入出力の例

たとえば、p = [4, 3, 7]q = [5, 9, 10]m = 11 という入力の場合、出力は True になります。理由を確認してみましょう。

  • カップの合計数は 4 + 3 + 7 = 14 個。1棚あたり5個なので、必要な棚は 3 棚
  • ソーサーの合計数は 5 + 9 + 10 = 24 枚。1棚あたり10枚なので、必要な棚は 3 棚

したがって、必要な棚の合計は 3 + 3 = 6 棚となり、与えられた棚の数 m = 11 よりも少ないため、True が返されます。

解法のアルゴリズム

この問題は、以下の手順で解くことができます。

  1. 合計値を格納する変数 sum_p と sum_q を 0 で初期化する
  2. 配列 p の全要素を sum_p に加算し、カップの総数を求める
  3. 配列 q の全要素を sum_q に加算し、ソーサーの総数を求める
  4. 切り上げ除算により、カップに必要な棚数 m_p を計算する
  5. 同様に、ソーサーに必要な棚数 m_q を計算する
  6. m_p + m_q が m 以下なら True、そうでなければ False を返す

実装例

理解を深めるために、実際のコードを見てみましょう。

def is_valid(p, q, m):
    sum_p = 0
    sum_q = 0
    for i in range(len(p)):
        sum_p += p[i]
    for i in range(len(q)):
        sum_q += q[i]
    # 切り上げ除算で必要な棚数を計算
    m_p = (sum_p + 5 - 1) // 5
    m_q = (sum_q + 10 - 1) // 10
    if m_p + m_q <= m:
        return True
    else:
        return False

p = [4, 3, 7]
q = [5, 9, 10]
m = 11

print(is_valid(p, q, m))

入力

[4, 3, 7], [5, 9, 10], 11

出力

True

コードのポイント

(sum_p + 5 - 1) // 5 のような計算は、切り上げ除算(天井関数)を実現する定番のテクニックです。整数除算演算子 // を使うことで、小数点以下を切り上げた棚数を正確に求められます。

また、Pythonでは組み込み関数 sum()math.ceil() を使うと、より簡潔に書くこともできます。

import math

def is_valid(p, q, m):
    m_p = math.ceil(sum(p) / 5)
    m_q = math.ceil(sum(q) / 10)
    return m_p + m_q <= m

どちらの実装でも計算量は O(n + m) 程度に収まり、非常に効率的に判定できます。

  1. Pythonで二分探索木(BST)の中央値をO(n)時間・O(1)空間で求める方法

    問題の概要 二分探索木(Binary Search Tree、BST)が与えられたとき、その中央値を求めることを考えます。ノードの総数を n とすると、中央値は次のように定義されます。 n が奇数の場合: 中央値 = 中序順(昇順)で (n+1)/2 番目のノードの値 n が偶数の場合: 中央値 = (n/2 番目のノードの値 + (n+1)/2 番目のノードの値) / 2 例として、次のようなBSTを考えてみましょう。 7 / \ 4 9 / \ / \ 2 5 8 10 この木の中序走査(昇順)の結

  2. PythonとOpenCVで画像の輪郭を検出・描画する方法

    画像解析を行う際には、Python向けのオープンソースライブラリ「OpenCV(Open Source Computer Vision Library)」が広く利用されています。OpenCVをインストールした後、プログラム内では「cv2」という名前でインポートして使用します。 本記事では、画像ファイルに含まれる輪郭(コンタ)を検出し、描画する方法を解説します。輪郭とは、画像内の物体の形状を把握するために重要な情報で、「同じ明るさ(輝度)を持つ領域の境界上にある点を結んだ線」として定義されます。OpenCVでは、輪郭の検出にfindContours関数、輪郭の描画にdrawContours関数を