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

C++で指定された条件を満たす最初のN個の自然数の順列を求めるアルゴリズム

2つの整数 NK が与えられたとき、最初の N 個の自然数からなる順列 P のうち、すべての 1 ≤ i ≤ N に対して GCD(P[i], i) > 1 を満たす要素がちょうど K 個になるような順列を求める問題を考えてみましょう。

例えば、N = 3、K = 1 の場合、答えは「2, 1, 3」になります。実際に確認すると、gcd(2, 1) = 1、gcd(1, 2) = 1、gcd(3, 3) = 3 となり、条件を満たす要素は1つだけであることがわかります。

解法のアプローチ

この問題の解法は非常にシンプルです。末尾の K 個の要素は元の位置にそのまま残し、残りの要素を1つずつ後ろにずらします。具体的には、i 番目の要素を (i + 1) 番目の位置へ移動させ、(N − K) 番目の要素を先頭(1番目)の位置に配置します。

これがうまく機能する理由は、隣り合う整数の最大公約数は必ず1になる(gcd(x, x+1) = 1)という性質によるものです。ずらされた部分では条件を満たす要素が生じず、そのまま残した末尾の K 個の要素のみが gcd(P[i], i) = i > 1 を満たすため、ちょうど K 個という要件を達成できます。

サンプルコード

#include<iostream>
using namespace std;

void findPermutation(int n, int k) {
    int permutation[n + 1];
    // 初期状態として permutation[i] = i を設定
    for (int i = 1; i <= n; i++)
        permutation[i] = i;
    // 先頭側の要素を1つ後ろへずらす
    for (int i = 1; i < n - k; i++)
        permutation[i + 1] = i;
    // (N - K) 番目の値を先頭に配置
    permutation[1] = n - k;
    // 結果の出力
    for (int i = 1; i <= n; i++)
        cout << permutation[i] << " ";
}

int main() {
    int n = 5, k = 2;
    cout << "The permutation is: ";
    findPermutation(n, k);
}

実行結果

The permutation is: 3 1 2 4 5

出力「3 1 2 4 5」を検証してみると、gcd(3, 1) = 1、gcd(1, 2) = 1、gcd(2, 3) = 1 であり、条件を満たすのは gcd(4, 4) = 4 と gcd(5, 5) = 5 の2箇所だけです。つまり K = 2 の要件を正確に満たしていることが確認できます。

このアルゴリズムの計算量は O(N) であり、配列を一度走査するだけで順列を構築できるため、非常に効率的です。

  1. PHPで最初のn個の偶数の平均を求めるプログラム

    はじめに 最初のn個の偶数(2、4、6、8、…、2n)の平均は、実はとてもシンプルな式で表すことができます。偶数の合計は 2 + 4 + … + 2n = n(n + 1) となるため、これを個数 n で割ると、平均は必ず n + 1 になります。 この数学的性質を活かせば、ループで合計を計算する必要すらなく、定数時間 O(1) で答えを導き出せます。以下がそのPHPコードです。 サンプルコード <?php function even_nums_avg($val) {     return $val + 1; } $val = 11; print_

  2. Pythonで最初のN個の自然数の順列から、中央値がMとなる部分配列の個数を求める方法

    問題の概要 最初のN個の自然数の順列を並べ替えた配列Aと整数M(ただし M ≤ N)が与えられたとします。このとき、中央値がMとなる部分配列(連続する要素からなる部分列)の個数を求めるのが本記事の目的です。 なお、ここでの中央値とは、数列を昇順にソートした際に中央に位置する要素の値を指します。長さが偶数の数列については、中央に並ぶ2つの要素のうち左側(小さい方)を採用します。 例として、入力が A = [3, 5, 6, 4, 2]、M = 5 の場合を考えてみましょう。条件を満たす部分配列は [3, 5, 6]、[5]、[5, 6]、[5, 6, 4] の4つであるため、答えは 4 となりま