ブルーブリッジカップ式の問題(すべての順列)

1.問題の説明:

この質問は空欄を埋める質問です。結果を計算した後、コードの出力文を使用して、埋められた結果を出力します。次の式を見てください:☆☆☆+☆☆☆=☆☆☆、それぞれの五芒星が1から9までの異なる数を表す場合。この数式を入力するための可能な正しい方法はいくつありますか?
173 + 286 = 459295
+ 173 = 468173
+ 295 = 468183
+ 492 = 675

上記は正しい記入方法です!注:111 + 222 = 333は間違った入力方法です!それぞれの番号は異なっている必要があるからです!言い換えると、11から9までのすべての数字は、それぞれが表示される必要があり、1回だけ表示される必要があります。
注:「0」と「0」の数字は含まれていません。
注:加算の為替レートを満たす式は、2つの異なる回答としてカウントされます。したがって、答えは偶数でなければなりません!
動作制限
最大動作時間:1秒
最大動作メモリ:128M
出典:https://www.lanqiao.cn/problems/731/learning/

2.思考分析:

①質問を分析すると、これらの9つの数を1回だけ出現させる必要があることがわかり、加算の可換法則を満たす式は2つの異なる答えとしてカウントされるため、この特徴に従って、完全な配置を考えます。最初に、数値を宣言します。1〜9のリストの場合、リスト内の各位置で数値を交換して、すべての完全な順列を生成します。完全な順列を生成するための交換は、実際には、再帰的な交換方法を使用することで比較的簡単にできます。 、および完全な順列(再帰的終了)が生成されるときはいつでも、リスト内の9つの数値のそれぞれをグループに分割して、3つの3桁の数値を形成する必要があります(9つの数値の完全な配列を生成し、残りは比較的簡単です) 、次に最初の数と最初の数を決定します。2つの数の加算は3番目の数と等しいですか?等しい場合、カウントは1ずつ増加します。再帰が終了した後、カウント結果が最終的に返されます。この質問の核心は、完全な配列を生成するための交換の再帰的方法を生成する方法です。

②まず、最初のリストは[1,2,3,4,5,6,7,8,9]のようになります。スワッピングして並べ替えを生成するプロセスは、実際には現在の位置の数値を結合することです。 with [k、8]範囲内の数値が交換され(それ自体と交換すると置換も生成される可能性があります)、各位置はこのようになるため、forループで再帰する必要があり、forループでの再帰は次のようになります。 try and k and after k 8の位置の数値が交換されます。つまり、現在の交換位置を示すために、再帰メソッドでintタイプのパラメーターを渡す必要があり、現在の再帰レベルが完了すると、バックトラックが実行されます。が必要であるため、結果は正しくなります。バックトラックの目的は、現在のレベルの再帰が終了した後、再帰前の状態に復元し、次の交換を試行して再帰を続行することです。したがって、コアコードは再帰前の番号交換です。再帰後のバックトラック:

③完全な順列の言い回しを習得するのはとても良いと思います(特に完全な順列を生成するためのスワッピングの方法、コードは非常に短い、実際、覚えておくのは害はありません)、いくつかの暫定的な質問を変換することができます1〜9の数字に分けます。処理を手配します。このソリューションは、状況によっては良いソリューションですよね?

3.コードは次のとおりです(答えは336のようです)。

from typing import List


# 使用全排列的方法进行解决
def permutation(k: int, nums: List[int], res: List[int]):
    if k == len(nums):
        # print(nums)
        first, second, third, base = 0, 0, 0, 1
        # 将列表中的值转换为三组三位数字
        for i in range(3):
            first += nums[2 - i] * base
            second += nums[5 - i] * base
            third += nums[8 - i] * base
            base *= 10
        if first + second == third:
            # 可以对结果进行输出看是否正确
            #print(first, second, third)
            res[-1] += 1
        return
    for i in range(k, len(nums)):
        # 将k位置上的数字与k~8位置上的数字进行交换
        t = nums[i]
        nums[i] = nums[k]
        nums[k] = t
        permutation(k + 1, nums, res)
        # 回溯, 将列表恢复为递归前的状态, 尝试下一次=个的交换
        t = nums[i]
        nums[i] = nums[k]
        nums[k] = t


if __name__ == '__main__':
    nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    # 因为使用全局变量很麻烦所以使用了一个值的列表来存储递归状态计数的问题
    res = [0]
    permutation(0, nums, res)
    print(res[0])

 

おすすめ

転載: blog.csdn.net/qq_39445165/article/details/115189349