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

C++で任意の2つの要素の差がkで割り切れるm個の要素のセットを見つける方法

問題の概要

N個の正の整数からなる配列と、変数Kが与えられたとします。この中から、任意の2つの要素の差がKで割り切れるような、ちょうどm個の要素のセットを見つける必要があります。

例えば、配列 A = [4, 7, 10, 6, 9]、k = 3、m = 3 の場合、出力は「Yes」になります。4、7、10 という3つの要素が条件を満たすからです。

解法のアプローチ

この問題を効率的に解く鍵となるのは、各要素を k で割った余り(剰余)に注目することです。同じ余りを持つ2つの要素の差は、必ず k で割り切れるという性質を利用します。

具体的な手順は以下のとおりです。

  • サイズ k の2次元配列 rem[][] を作成します。インデックスが余りを表し、各要素には対応する余りを持つ元の配列の値を格納します。
  • 配列を1回走査し、各要素を余りごとに分類します。
  • 余りのグループを調べ、サイズが m 以上のグループが存在すれば、その中から任意の m 個の要素を選ぶことで条件を満たすセットが得られます。

C++での実装例

#include<iostream>
#include<vector>
using namespace std;
void searchElementsSet(int arr[], int n, int k, int m) {
   vector<int> rem_matrix[k];
   for (int i = 0; i < n; i++) {
      int rem = arr[i] % k;
      rem_matrix[rem].push_back(arr[i]);
   }
   for (int i = 0; i < k; i++) {
      if (rem_matrix[i].size() >= m) {
         cout << "Yes Possible"<<endl;
         for (int j = 0; j < m; j++)
            cout << rem_matrix[i][j] << " ";
         return;
      }
   }
   cout << "Impossible";
}
int main() {
   int arr[] = {4, 7, 10, 6, 9};
   int k = 3;
   int m = 3;
   int n = sizeof(arr) / sizeof(arr[0]);
   searchElementsSet(arr, n, k, m);
}

出力結果

Yes Possible
4 7 10

計算量

このアルゴリズムの時間計算量は O(n)、必要な追加メモリの空間計算量も O(n) です。配列を1回走査して余りごとに分類するだけなので、非常に効率的な手法と言えます。

まとめ

「差がkで割り切れる要素の集合を見つける」という一見複雑な問題も、剰余に着目して要素をグループ化することでシンプルに解決できます。同じ余りのグループ内の要素同士は必ず条件を満たすため、グループのサイズが m 以上かどうかを確認するだけで答えが求まります。

  1. C++で行列の2つの対角線の合計の差を求める方法

    本記事では、与えられた行列における2つの対角線(主対角線と副対角線)の要素の合計の差を求める方法について解説します。N×Nの正方行列が与えられたとき、まず主対角線と副対角線それぞれの合計を計算し、その差の絶対値を求めて結果として返します。アルゴリズムの考え方主対角線(左上から右下へ向かう対角線)では、行インデックスと列インデックスが同時に増加していきます。つまり、matrix[i][i] の要素を順に加算することで合計を求められます。一方、副対角線(右上から左下へ向かう対角線)では、行インデックスと列インデックスの間に「row_index = n − 1 − col_index」という関係が成

  2. C++で指定された差分を持つペアを見つける方法

    はじめに 配列 A に n 個の異なる要素が格納されているとします。この配列から、2つの要素 x と y の差が指定された値 d と一致するようなペア (x, y) をすべて見つける必要があります。 例として、配列が A = [10, 15, 26, 30, 40, 70]、指定された差分が 30 である場合を考えます。このとき、該当するペアは (10, 40) と (40, 70) です。 解法:ツーポインタ法 この問題は、配列が昇順にソートされていることを前提とすれば、ツーポインタ(二重インデックス)法を使って効率的に解くことができます。まず、1つ目のポインタ「i」を先頭の要素に、2つ目の