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

Pythonで解く素数の並べ替え問題:素数を素数インデックスに配置する順列の数


この記事では、1からnまでの数字を使った順列のうち、「素数が素数のインデックス位置(1始まり)に配置されている」ものの総数を求める問題を扱います。答えは非常に大きくなる可能性があるため、109 + 7で割った余りを返します。

例えば n = 5 の場合、答えは12通りになります。有効な順列の一例は [1, 2, 5, 4, 3] です。一方、[5, 2, 3, 4, 1] は無効です。これは、素数である5がインデックス1(素数ではない)に置かれているためです。

解法のアプローチ

まず、getNum という補助メソッドを定義して n 以下の素数の個数を数えます。その後、素数の個数 x と非素数の個数 n − x それぞれについて階乗を計算し、掛け合わせることで答えを求めます。

  • getNum メソッド: 2から100までの素数リストを用意し、リストを先頭から走査します。n より大きい素数が出現した時点でのカウント(= n 以下の素数の個数)を返します。
  • メイン処理: x = getNum(n)、p = 1、m = 109 + 7 とします。まず i を x から 1 まで減らしながら p *= i、p %= m を繰り返します。続いて i を n − x から 1 まで減らしながら同じ計算を行い、最終的な p を返します。

なぜこの方法で正しいのか

n 以下に素数が x 個あるとき、x 個の素数を x 個の素数インデックスへ配置する方法は x! 通りあります。同様に、残りの n − x 個の数(1と合成数)を n − x 個の非素数インデックスへ配置する方法は (n − x)! 通りあります。この2つの配置は互いに独立しているため、答えは x! × (n − x)! となります。毎回の剰余演算によって値の肥大化を防ぎ、オーバーフローなしに計算できます。

実装例

以下のPythonコードで実際の動作を確認できます。

class Solution(object):
    def getNum(self,n):
        primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
        i = 0
        while i < len(primes):
            if primes[i]>n:
                return i
            i+=1
        return len(primes)
    def numPrimeArrangements(self, n):
        """
        :type n: int
        :rtype: int
        """
        x = self.getNum(n)
        p = 1
        m = 1000000000+7
        for i in range(x,0,-1):
            p*=i
            p%=m
        for i in range(n-x,0,-1):
            p*=i
            p%=m
        return p
ob1 = Solution()
print(ob1.numPrimeArrangements(100))

入力

100

出力

682289015

n = 100 の場合、100以下の素数は25個存在するため、答えは 25! × 75! を 109 + 7 で割った余りである 682289015 となります。

  1. Pythonで数値の一意な素因数の積を求める方法

    この記事では、以下の問題文に対する解決策について学びます。問題文数値 n が与えられたとき、その数値が持つすべての一意な素因数の積を求めて返します。例入力: num = 11 出力: 積は 11説明ここでは、入力された数値は 11 であり、素因数は 11 のみです。したがって、その積は 11 となります。アプローチ1:総当たり法i = 2 から n+1 までの for ループを使用し、i が n の因数であるかどうかを確認します。因数であれば、さらに i 自体が素数かどうかを判定し、素数であれば product 変数に積を格納します。この処理を i が n になるまで繰り返します。コード例de

  2. 【初心者向け】Pythonのissuperset()メソッドの使い方をわかりやすく解説

    はじめにこの記事では、Pythonのissuperset()メソッドについて、基本的な仕組みから実際のコード例まで詳しく解説します。issuperset()は、セット(集合)に対して使用できるメソッドで、引数として渡されたセットのすべての要素が、呼び出し元のセットに含まれているかどうかを判定します。呼び出し元のセットBが、引数のセットAのすべての要素を含んでいる場合 → True を返すセットAの要素がすべてBに含まれていない場合 → False を返すつまり、「BがAの上位集合(スーパーセット)であるかどうか」を判定するためのメソッドです。基本構文B.issuperset(A)この式は、Bが