-
C++でN個のバイナリ文字列のビットごとのAND(論理積)を計算する方法
この問題では、サイズnのバイナリ文字列からなる配列 bin[] が与えられます。私たちの課題は、N個のバイナリ文字列すべてのビットごとのAND(&)を求めるプログラムを作成することです。具体的には、すべての数値に対してビットごとのANDを適用します。つまり、bin[0] & bin[1] & ... & bin[n-2] & bin[n] のような形で計算を行います。問題を理解するための具体例入力:bin[] = {1001, 11001, 010101}出力:000001説明: すべてのバイナリ文字列に対してビットごとのANDを適用すると、以下の結果が得られます。(1001) & (1100
-
C++で実装する「Kに最も近い部分配列のビットごとのAND」問題の解法
問題の概要この問題では、サイズ n の配列 arr[] と整数 k が与えられます。私たちのタスクは、インデックス i から j までの部分配列を選び、そのすべての要素のビットごとのAND(論理積)を計算することです。その後、|K − (部分配列のビットごとのAND)| の最小値を出力します。具体例で問題を確認してみましょう。入力: arr[] = {5, 1}, k = 2この場合、考えられる部分配列は {5}、{1}、{5, 1} であり、それぞれのAND値は 5、1、1 となります。k = 2 との差の絶対値はそれぞれ 3、1、1 なので、答えは 1 になります。解法1: 全探索によるシ
-
C++で範囲内のすべての整数のビットごとのOR(|)を効率的に計算する方法
この問題では、2つの整数値 a と b が与えられ、a から b までの範囲に含まれるすべての整数のビットごとのOR(|)を求めることが課題となります。つまり、a | a+1 | a+2 | … | b-1 | b の値を計算する必要があります。 問題の例 入力 − a = 3、b = 8 出力 − 15 解説 − 3 | 4 | 5 | 6 | 7 | 8 = 15 シンプルな解法 最も単純な解法は、a から開始し、1ずつ増やしながら b までのすべての数値のビットごとのORを順番に計算していく方法です。この方法は理解しやすい反面、範囲が大
-
C++でN個のバイナリ文字列のビット単位OR(論理和)を計算する方法
問題の概要この問題では、n 個のバイナリ文字列からなる配列 bin[] が与えられます。私たちの課題は、これら n 個のバイナリ文字列すべてのビット単位OR(論理和)を求めるプログラムを作成することです。具体的には、すべての文字列に対して次のような演算を行います。bin[0] | bin[1] | ... | bin[n-2] | bin[n-1]それでは、具体例を使って問題を理解しましょう。入力:bin[] = {1001, 11001, 010101}出力:011101説明: すべてのバイナリ文字列のビット単位ORは以下のように計算されます。(1001) | (11001) | (0101
-
C++のビット単位のふるい(Bitwise Sieve)で素数を効率的に求める方法
この記事では、整数 N が与えられたとき、ビット単位のふるい(Bitwise Sieve)を用いて N 未満のすべての素数を効率よく求める方法を解説します。 ビット単位のふるいとは? ビット単位のふるいは、指定された数より小さいすべての素数を列挙するために用いられる、エラトステネスの篩(Sieve of Eratosthenes)の最適化版です。 通常のエラトステネスの篩では、各数値が素数かどうかを bool 型(1バイト)で管理します。一方、ビット単位のふるいでは整数型の各ビット(1ビット)で素数判定情報を表現します。bool 型は1バイト(8ビット)を消費するため、この手法を採用することで
-
C++で学ぶBKツリー:レーベンシュタイン距離によるスペルチェックの仕組みと実装
BKツリー(Burkhard-Kellerツリー)とは BKツリーは、レーベンシュタイン距離(編集距離)に基づくスペルチェックによく使われるデータ構造です。文字列マッチングや自動修正(オートコレクト)機能の実装にも応用できます。 例えば、辞書に登録された単語の中から、チェック対象の単語に近い綴りの候補を集めたい場面を考えてみましょう。入力が「uck」だった場合、正しい単語としては「truck」「duck」「suck」などが考えられます。このように、文字の削除・追加・置き換えによって生じるスペルミスは、編集距離をパラメータとして辞書内の単語と照合することで修正できます。 木の構造 他の木構造と
-
C++での配列回転をO(n)で実現!ブロックスワップアルゴリズムの解説
ブロックスワップアルゴリズム(Block Swap Algorithm)は、配列の回転(ローテーション)を効率的に実行するためのアルゴリズムです。最大の特徴は、O(n) の時間計算量で処理を完了できる点にあります。 配列の回転では、サイズ n の配列 arr[] と、先頭から回転する要素数を指定する整数 k が与えられます。 配列回転の具体例 入力: arr[] = {4, 6, 1, 8, 9, 2}, k = 2(回転する要素数) 出力: {1, 8, 9, 2, 4, 6} 解説: 回転では、先頭の要素を末尾へ移動させ、残りの要素を1つずつ前方へずらします。つまり、インデックス0の要素は
-
C++でリンクリスト内の各ノードの小さい方の要素を合計する方法
この問題では、2つの整数値(X と Y)と次のノードへのポインタを持つノードから構成されるリンクリストが与えられます。求めるのは、各ノードにおける小さい方の値をすべて合計した結果です。リンクリストの各ノードには X と Y という2つの値が格納されています。プログラムは各ノードごとに X と Y を比較して小さい方を選び、それらをすべて足し合わせた値を出力します。入力例(5,2)->(7,9)->(6,3)->(36,24)->(19,26)->null出力例55計算の流れ各ノードで X と Y のうち小さい方の値を取り出します。node1 - 最小値 = 5 n
-
【C++】3つの配列の要素からなる特別なトリプレットの合計を求める方法
この記事では、3つの配列 X、Y、Z が与えられたときに、それぞれの配列から1つずつ要素を選んで構成できる「特別なトリプレット」の合計値を求めるプログラムを紹介します。 特別なトリプレットとは? 特別なトリプレットとは、次の性質を満たす三つ組のことです。 (a, b, c):a ≤ b かつ b ≥ c つまり、トリプレットの中央にある要素 b が、両端の要素 a および c 以上でなければなりません。 そして、トリプレットの値は次の式で定義されます。 f(a, b, c) = (a+b) * (b+c) 具体例で理解しよう 入力: X[] = {5, 9, 4} ; Y[] = {8, 6}
-
C++で級数 1² + 3² + 5² + … + (2n−1)² の総和を求める方法
問題概要本記事では、整数 n が与えられたとき、級数 1² + 3² + 5² + … + (2n−1)² の総和を求める方法を解説します。この級数は「最初の n 個の奇数の平方の和」を表しており、競技プログラミングや学習の題材としてよく登場します。入力例と出力例入力:n = 5出力:165計算過程:sum = 1² + 3² + 5² + 7² + 9² = 1 + 9 + 25 + 49 + 81 = 165それでは、この問題を解くための2つのアプローチを順に見ていきましょう。方法1: ループを使った基本的な解法最もシンプルな方法は、for ループで 1 から n まで順番
-
【C++解説】文字列とそのすべての接尾辞との類似度の合計を求める方法
この問題では、文字列 str が与えられます。求めるのは、元の文字列とそのすべての接尾辞(サフィックス)との類似度の合計です。接尾辞と類似度とは?接尾辞とは、文字列の先頭から文字を削除していくことで生成されるすべての文字列のことです。類似度とは、2つの文字列 str1 と str2 の間で共通する最長接頭辞(プレフィックス)の長さを指します。例1:str1 = ‘abbac’、str2 = ‘abb’ の場合 → 共通接頭辞は ‘abb’ なので類似度は 3例2:str1 = ‘abca’、str2
-
C++で部分集合の差の合計を求める効率的なアルゴリズム
問題の概要この問題では、n個の数からなる集合Sが与えられ、各部分集合sについて「最後の要素と最初の要素の差」を計算し、その総和を求めるプログラムを作成します。数式で表すと次のようになります。sumSubsetDifference = Σ [last(s) − first(s)]※ sは集合Sの部分集合入出力例で理解しよう入力 −S = {1, 2, 9} n = 3出力 − 24説明 − すべての部分集合とその差は以下の通りです。{1}, last(s) − first(s) = 0{2}, last(s) − first(s) = 0{9}, last(s) − first(s) = 0{1
-
C++で2と7で割り切れる自然数の合計を求める方法|包除原理による効率的なアルゴリズム
問題概要 本記事では、整数Nが与えられたとき、1からNまでの自然数のうち「2または7で割り切れる数」の合計を求めるアルゴリズムをC++で解説します。 一見すると「2と7の両方で割り切れる数」と誤解されやすいのですが、実際に求めるのは「2で割り切れる、または7で割り切れる」数の総和です。この点を正しく理解することが、適切な解法へたどり着く第一歩となります。 具体例で問題を確認しよう 入力: N = 10 出力: 37 解説: 1から10までの自然数の中で、2または7で割り切れるのは「2, 4, 6, 7, 8, 10」の6つです。これらをすべて足し合わせると、 sum = 2 + 4 + 6
-
【C++】配列内の倍数の個数を求めるクエリ処理の実装方法
この記事では、整数型の配列 arr[] と、それぞれ値 m を持つ Q 個のクエリが与えられたとき、「配列内に m の倍数がいくつ含まれているか」を答えるプログラムを C++ で実装する方法を解説します。 問題の概要 各クエリに対して、配列内の要素のうち m で割り切れるもの(すなわち m の倍数)の個数を数えて出力します。 具体例で確認してみましょう。 入力:arr[] = {4, 7, 3, 8, 12, 15}Q = 3、query[] = {2, 3, 5} 出力:3 3 1 出力の解説 クエリ1:m = 2 のとき、配列内の倍数は 4, 8, 12 の 3 つなので、個数は 3。
-
【C++】指定範囲内の値を持つ配列要素の個数を求めるクエリ処理の実装方法
この問題では、配列 arr[] と Q 個のクエリが与えられます。各クエリは次の2種類のいずれかです。{1, L, R} … 範囲 [L, R] 内の値を持つ配列要素の個数を求める{2, index, val} … index の位置にある要素を val に更新する本記事では、これらのクエリを効率的に処理するC++プログラムの作成方法を、2つのアプローチに分けて解説します。問題の例入力:arr[] = {1, 5, 2, 4, 2, 2, 3, 1, 3} Q = 3 Query = { {1, 4, 8}, {2, 6, 5}, {1, 1, 4}}出
-
【C++】指定した範囲内の素数の最大差を求めるクエリ問題の解法
この記事では、2つの値 L と R から構成される Q 個のクエリが与えられたとき、それぞれの範囲内に存在する素数のうち「最大の素数」と「最小の素数」の差(最大差)を求めるプログラムを C++ で実装する方法を解説します。問題の概要各クエリには2つの整数 L と R が与えられます。私たちのタスクは、区間 [L, R] 内に存在する素数を調べ、その中で最大の素数と最小の素数の差を計算することです。なお、範囲内に素数が1つも存在しない場合は 0 を出力します。具体例を使って問題を理解しましょう。入力Q = 3 4 15 32 37 54 1100出力For query 1: The maximu
-
C++でバイナリ配列の部分配列から10進数値を求めるクエリを効率的に処理する方法
この記事では、バイナリ配列 bin[] と、それぞれ2つの値 L と R からなる Q 個のクエリが与えられたときに、各部分配列(サブ配列)に対応する10進数値を求めるクエリをC++で解くプログラムの作成方法を解説します。問題の概要各クエリに対して、インデックス L から R までの部分配列 subarray[L...R] が表す2進数を求め、それを10進数に変換した結果を出力する必要があります。具体例を使って問題を確認してみましょう。入力例bin[] = {1, 1, 0, 0, 1, 0, 1, 0, 0, 0} Q = 2 2 5 0 6出力例2 101解説クエリ1の場合: 部分配列は
-
C++で部分文字列内の文字出現頻度クエリを効率的に解く方法
この問題では、1つの文字列と Q 個のクエリが与えられます。各クエリは 2 つの整数 l・r と 1 文字 ch で構成されており、部分文字列 str[l...r] に含まれる文字 ch の出現回数を求めるプログラムを C++ で作成するのが課題です。 問題の概要 各クエリに対して、部分文字列 str[l...r] の中に文字 ch が何回出現するかを答えます。 入力例 str = tutorialspoint Q = 2 0 6 t 5 13 i 出力例 2 2 出力の解説 クエリ1: 部分文字列は「tutoria」となり、文字 t は 2 回出現します。 クエリ2: 部分文字列は「ials
-
C++で部分配列内の異なる要素の数をクエリ処理で求める方法
この記事では、サイズ n の配列 arr[] と、範囲を指定する2つの値 l・r からなる Q 個のクエリが与えられたとき、C++ を使って各部分配列(サブ配列)に含まれる異なる要素(ユニークな要素)の数を効率的に求めるプログラムの作成方法を解説します。問題の概要各クエリに対して、arr[l] から arr[r] までの部分配列に含まれる相異なる整数の総数を求める必要があります。同じ値が複数回現れても、それは1つとしてカウントします。具体例で理解しよう入力arr[] = {5, 6, 1, 6, 5, 2, 1} Q = 2 {{1, 4}, {0, 6}}出力3 4説明クエリ1の場合:l =
-
部分配列内の異なる要素数をクエリで求める方法 | C++でのセグメント木とsetによる実装
この記事では、サイズ n の配列 arr[] が与えられ、各クエリが2つの値 (L, R) を持つという問題を扱います。目標は、部分配列に含まれる異なる(ユニークな)要素の数を答えるプログラムを作成することです。 問題の説明 ここで求めるのは、インデックス L-1 から R-1 までの部分配列内に存在する、重複しない整数の合計数です。 具体例で理解しよう 入力 arr[] = {4, 6, 1, 3, 1, 6, 5} query = [1, 4] 出力 4 説明 クエリ1: L = 1、R = 4 の場合、インデックス0から3までの範囲({4, 6, 1, 3})に含まれる異なる要素の数は