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

Pythonで配列を2つのサブ配列に分割し、合計の差が指定した数値になるか判定する方法


整数を要素とする配列「input_list」が与えられたとしましょう。この問題では、配列を2つの部分に分割したとき、それぞれの合計値の差が、あらかじめ指定された数値 n と一致するようにできるかどうかを判定します。

たとえば、input_list = [9, 2, 5, 6]、n = 0 という入力が与えられた場合、出力は「Possible」になります。[9, 2] と [5, 6] に分割すれば、両方の合計が11となり、差がちょうど0になるためです。

解決のアプローチ

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

  • list_total に input_list の全要素の合計を代入する
  • (list_total − n) を2で割った余りが1の場合(奇数の場合)は「Not Possible」を返す
  • val に (list_total − n) / 2 を代入する
  • temp_sum を0で初期化する
  • i を0から input_list のサイズまでループさせる
    • temp_sum に input_list[i] を加算する
    • temp_sum が val と一致した時点で「Possible」を返す
  • ループが終了しても条件を満たさなければ「Not Possible」を返す

このアルゴリズムのポイントは、先頭からの累積和(プレフィックスサム)が (全体の合計 − n) / 2 と一致する位置で配列を区切ると、前半と後半の合計の差がちょうど n になるところにあります。また、(list_total − n) が奇数の場合は、整数の合計値同士で差 n を実現することができないため、最初の段階で不可能と判断できます。

それでは、実際の実装を見て理解を深めましょう。

コード例

def solve(input_list, n):
    list_total = sum(input_list)
    if (list_total - n) % 2 == 1:
        return "Not Possible"
    val = (list_total - n) / 2
    temp_sum = 0
    for i in range(0, len(input_list)):
        temp_sum += input_list[i]
        if temp_sum == val:
            return "Possible"
    return "Not Possible"

input_list = [9, 2, 5, 6]
n = 0
print(solve(input_list, n))

入力

[9, 2, 5, 6], 0

出力

Possible
  1. Pythonでチェス盤を2つに分割せずに入れられるカットの最大数を求める方法

    ここでは、A × B のサイズのチェス盤(マトリクス)が与えられたとき、盤面が2つに分割されてしまわないように入れられるカットの最大数を計算する方法を解説します。 例として、A = 2、B = 4 のケースを考えてみましょう。 この場合の出力は 3 となります。 解き方のアプローチ この問題は、次の手順で解くことができます。 結果を格納する変数 res を 0 で初期化します。 res に (M − 1) × (N − 1) を代入します。 res を返します。 この式のポイントは、盤を2つに分割してしまわないためには、盤の端から端まで貫通する完全な切断は行えないという点です。そのため、

  2. Pythonで配列を等しい合計のサブ配列に分割できる合計値を見つける方法

    整数の配列Aが与えられたとき、ある値sum[i]ごとに、配列を合計がsum[i]となる複数のサブ配列に分割できるような、すべての合計値を見つける必要があります。もし配列を等しい合計のサブ配列に分割できない場合は、-1を返します。 例えば、入力が A = [2, 4, 2, 2, 2, 4, 2, 6] の場合、出力は [6, 8, 12] になります。これは、配列を合計が6、8、12となるサブ配列にそれぞれ分割できるためです。具体的な分割例は以下の通りです。 合計6の場合: {2, 4}, {2, 2, 2}, {4, 2}, {6} 合計8の場合: {2, 4, 2}, {2, 2, 4}