LeetCodeは毎日の質問1175に焦点を当てています。素数の配置

すべての「素数」が「素数インデックス」(インデックスは 1 から始まります)に配置されるように、1 から n までの数値の配置を設計するのを手伝ってください。可能な解の総数を返す必要があります。

一緒に「素数」について復習しましょう。素数は 1 より大きくなければならず、それより小さい 2 つの正の整数の積で表すことはできません。

答えは非常に大きい可能性があるため、答えを mod 10^9 + 7 で返してください。

例 1:

输入:n = 5
输出:12
解释:举个例子,[1,2,5,4,3] 是一个有效的排列,但 [5,2,3,4,1] 不是,因为在第二种情况里质数 5 被错误地放在索引为 1 的位置上。

例 2:

输入:n = 100
输出:682289015

ヒント:

1 <= n <= 100

アイデア

  • 素数の位置は入れ替えることができ、非素数と非素数の位置も入れ替えることができます。
  • x 個の素数がある場合、x! 種類の順列が存在し、y 個の非素数がある場合、y! 種類の順列が存在し、x!*y! 種類の順列が存在します。
  • 知らせ
    • 各計算ステップでは、係数を取得する必要があります。
    • 中間変数を定義するには、long long を使用します。
    • 最終的に返された結果の剰余を取ることを忘れないでください。
#include "bits/stdc++.h"
using namespace std;

int MOD = 1e9 + 7;
int MAXN = 100;

class Solution {
    
    
public:
    void getPrime() {
    
    
        isPrime.resize(MAXN + 1, true);
        isPrime[0] = isPrime[1] = false;
        for (int i = 2; i <= MAXN; ++i) {
    
    
            if (isPrime[i]) {
    
    
                for (int j = 2 * i; j <= MAXN; j += i) {
    
    
                    isPrime[j] = false;
                }
            }
        }
    }

    int numPrimeArrangements(int n) {
    
    
        if (n == 1) {
    
    
            return 1;
        }
        getPrime();
        // 质数之间位置可以互换,非质数和非质数之间也可以互换
        // 若质数有x个,则有x!种排列;非质数有y个,则有y!中排列;则共有x!*y!种排列
        long long x = 0;
        for (int i = 1; i <= n; ++i) {
    
    
            if (isPrime[i]) {
    
    
                ++x;
            }
        }
        long long y = n - x;
        for (int i = x - 1; i >= 2; --i) {
    
    
            x = (x * i) % MOD;
        } 
        for (int i = y - 1; i >= 2; --i) {
    
    
            y = (y * i) % MOD;
        }
        return (x * y) % MOD;
    }

private:
    vector<bool> isPrime;
};
  • 素数ふるい法 ふるい
    法を使用して素数を見つける基本的な考え方:
    A (A>=2) が素数の場合、A の N (N>=2) 倍は素数であってはなりません。
    C
    ++ コード:
// 初始化为true
vector<int> isPrime(range + 1, true);
// 0和1都不是素数
isPrime[0] = isPrime[1] = false;
// 从2开始,将非素数设置为false
for (int i = 2; i <= range; ++i) {
    
    
	if (isPrime[i]) {
    
    
		for (int j = 2 * i; j <= range; j += i) {
    
    
			isPrime[j] = false;
		}
	}
}

最適化:

おすすめ

転載: blog.csdn.net/weixin_36313227/article/details/125535743