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

C++の整数のストリームで指定された整数の最大XORを見つけます


この問題では、それぞれが次のタイプのいずれかであるQクエリが与えられます

タイプ1 −データ構造に値iの要素を追加するための挿入(1、i)。

タイプ2 − findXOR(2、i)、要素iを持つデータ構造のすべての要素のXORを検索します。

データ構造には、最初は0になる要素を1つだけ含める必要があります。

問題を理解するために例を見てみましょう

入力

Queries: (1, 9), (1, 3), (1, 7), (2, 8), (1, 5), (2, 12)

出力

15 15

説明

Solving each query,
(1, 9) => data structure => {9}
(1, 3) => data structure => {9, 3}
(1, 7) => data structure => {9, 3, 7}
(2, 8) => maximum XOR(_, 8) = 15, XOR(7, 8)
(1, 5) => data structure => {9, 3, 7, 5}
(2, 12) => maximum XOR(_, 12) = 15, XOR(3, 12)

ソリューションアプローチ

この問題の解決策は、特殊なタイプの検索ツリーであるtrieデータ構造を使用して見つけることができます。各ノードに2つの子ノードがあるトライを使用して、数値の2進値を格納します。この後、タイプ1の各クエリのトライに数値の2進値を追加します。タイプ2のクエリの場合、指定された値のトライ内のパスを見つけ、レベルカウントで結果が得られます。

>

トライ訪問の詳細については、トライデータ構造。

ソリューションの動作を説明するプログラム

#include<bits/stdc++.h>
using namespace std;
struct Trie {
   Trie* children[2];
   bool isLeaf;
};
bool check(int N, int i) {
   return (bool)(N & (1<<i));
}
Trie* newNode() {
   Trie* temp = new Trie;
   temp->isLeaf = false;
   temp->children[0] = NULL;
   temp->children[1] = NULL;
   return temp;
}
void insertVal(Trie* root, int x) {
   Trie* val = root;
   for (int i = 31; i >= 0; i--) {
      int f = check(x, i);
      if (! val->children[f])
         val->children[f] = newNode();
         val = val->children[f];
   }
   val->isLeaf = true;
}
int solveQueryType2(Trie *root, int x){
   Trie* val = root;
   int ans = 0;
   for (int i = 31; i >= 0; i--) {
      int f = check(x, i);
      if ((val->children[f ^ 1])){
         ans = ans + (1 << i);
         val = val->children[f ^ 1];
      }
      else
      val = val->children[f];
   }
   return ans;
}
void solveQueryType1(Trie *root, int x){
   insertVal(root, x);
}
int main(){
   int Q = 6;
   int query[Q][2] = {{1, 9}, {1, 3}, {1, 7}, {2, 8}, {1, 5}, {2, 12}};
   Trie* root = newNode();
   for(int i = 0; i < Q; i++){
      if(query[i][0] == 1 ){
         solveQueryType1(root, query[i][1]);
         cout<<"Value inserted to the data Structure. value =
         "<<query[i][1]<<endl;
      }
      if(query[i][0] == 2){
         cout<<"The maximum XOR with "<<query[i][1]<<" is
         "<<solveQueryType2(root, query[i][1])<<endl;
      }
   }
   return 0;
}

出力

Value inserted to the data Structure. value = 9
Value inserted to the data Structure. value = 3
Value inserted to the data Structure. value = 7
The maximum XOR with 8 is 15
Value inserted to the data Structure. value = 5
The maximum XOR with 12 is 15

  1. C++で指定された値に最も近いk個の要素を検索します

    要素が少ない配列Aがあるとします。他に2つの値Xとkがあります。私たちのタスクは、配列AからXの最も近い要素のk個を見つけることです。要素Xが配列に存在する場合、それは出力に表示されません。 A =[12、16、22、30、35、39、42、45、48、50、53、55、56]およびX =35、k =4の場合、出力は30、39、42、45になります。 。 これを解決するために、二分探索アプローチを使用します。これを使用して、クロスオーバーポイントを取得します。クロスオーバーポイントのインデックスが見つかった場合、O(k)時間でk個の最も近い要素を出力できます。 例 #include<i

  2. C++で指定された製品のN個の整数の最大GCD

    2つの整数NとPがあるとします。PはN個の未知の整数の積です。これらの整数の可能な最大GCDを見つける必要があります。 N =3、P =24とすると、異なるグループは{1、1、24}、{1、2、12}、{1、3、8}、{1、4、6}、{2 、2、6}、{2、3、4}。 GCDは1、1、1、1、2、1です。したがって、ここで答えは2です。 Pのすべての素因数を見つけて、ハッシュマップに保存します。素因数がすべての整数で共通である場合、N個の整数の最大公約数は最大GCDになります。したがって、P =p 1の場合 k1 * p 2 k2 *…*p n kn 。ここで、piは素因