-
C++で解く:数のすべての約数に含まれる奇数桁の和の総和を求めるクエリ処理
本記事では、Q個のクエリを処理するプログラムを扱います。各クエリには正整数Nが与えられ、C++を用いて「Nのすべての約数に含まれる奇数の桁の和」の総和を求める方法を解説します。 問題の概要 各クエリを処理する手順は次のとおりです。まず数Nのすべての約数を求めます。続いて、各約数ごとに「奇数の数字のみを足し合わせた値(奇数桁の和)」を計算し、それらをすべて合計した結果を返します。 具体例で確認してみましょう。 入力 Q = 2, queries = {15, 8} 出力 15 1 計算の内訳 クエリ1:N = 15 の場合。15の約数は 1, 3, 5, 15 です。各約数の奇数桁の和は、それぞ
-
C++で解くビトニック数列への要素挿入クエリの解法
この問題では、ビトニック数列とQ個のクエリが与えられます。各クエリには1つの整数が含まれており、その整数を数列に挿入した後のビトニック数列の長さを毎回出力することが求められます。さらに、すべてのクエリの処理が終わった後に、最終的なビトニック数列を出力します。問題の概要ここでは、ビトニック数列と、それぞれ追加対象の整数を1つ含むQ個のクエリが与えられます。各クエリの要素を順番に数列へ追加し、その都度ビトニック数列の長さを返します。そして、すべてのクエリが完了した時点で、最終的なビトニック数列を出力します。ビトニック数列とはビトニック数列とは、ある点(ビトニックポイントと呼ばれます)まで単調に増加
-
C++で円の内部に含まれる点の数を求めるクエリ処理|効率的な解法を解説
この問題では、2次元平面上に存在するn個の点が与えられます。各点の座標は(x, y)です。私たちのタスクは複数のクエリを処理することです。各クエリでは整数Rが与えられ、原点(0, 0)を中心とする半径Rの円の内部に含まれる点の個数を求めます。 問題の概要 各クエリに対して、与えられたn個の点のうち、中心が原点(0, 0)、半径がRの円(円周の内側)に含まれる点の総数を出力します。 例で問題を理解しよう 入力 n = 5 2 1 1 2 3 3 -1 0 -2 -2 Query 1: 2 出力 1 説明 − このクエリで与えられた半径は2です。点(-1, 0)だけが円の内部にあり、残りの点はす
-
C++で指定サイズのバイナリ部分行列の個数を求めるクエリ処理
この問題では、n×mのサイズを持つバイナリ行列bin[][]が与えられ、q個のクエリすべてに対する答えを求めます。各クエリ(x, y)に対しては、全要素がy(0または1)で構成されるx×xサイズの部分行列の個数を出力する必要があります。 問題の概要 与えられたサイズの部分行列のうち、0と1のどちらか一方の値だけで構成されているもの、すなわち全要素が0のみ、または全要素が1のみで構成される正方形部分行列の総数を数えます。 具体例で問題を確認しよう 入力 n = 3 , m = 4 bin[][] = {{ 1, 1, 0, 1}, { 1, 1, 1, 0}, { 0, 1, 1, 1}} q
-
C++で実装するAho-Corasickアルゴリズム――複数パターンを同時に検索する強力な手法
この記事では、入力文字列とキーワード配列 arr[] が与えられた際に、文字列中に出現する配列内の全単語の位置を検出する問題を扱います。これを解決するために使用するのがAho-Corasick(エイホ・コラシック)アルゴリズムです。 文字列やパターンの検索はプログラミングにおいて非常に重要なテーマであり、優れたアルゴリズムほど実用的な応用範囲が広がります。Aho-Corasickアルゴリズムは、文字列検索を容易にする非常に重要かつ強力なアルゴリズムです。いわば辞書マッチング型のアルゴリズムで、複数の文字列を一度に同時照合できる点が最大の特徴です。実装にはTrie(トライ)データ構造が用いられ
-
C++で実装するAlexander Bogomolnyの順列生成アルゴリズム
本記事では、数値Nが与えられたとき、Alexander Bogomolnyの順序なし順列アルゴリズム(UnOrdered Permutation Algorithm)を用いて、1からNまでのすべての順列を求める方法を解説します。順列とは順列(permutation)とは、集合内の要素を一意に並べ替える方法の総数、またはその並べ方そのものを指します。例:{4, 9, 2}の順列は、{4, 9, 2}、{4, 2, 9}、{9, 4, 2}、{9, 2, 4}、{2, 4, 9}、{2, 9, 4}の6通りとなります。順列はコンピュータネットワークにおけるスイッチングネットワークの設計や、並列処理
-
C++で実装するベッセル補間:公式の解説とサンプルコード
補間(Interpolation)とは、既知の値の間にある未知の値を推定する手法の一つです。離散的な既知データ点の範囲内に新しいデータ点を構築するプロセスを指します。 補間を使用する主な理由の一つは、計算コストの削減です。ある値を求めるための数式(関数)が複雑すぎたり、計算に多大な時間やリソースが必要だったりする場合、補間が有効な選択肢となります。元の関数を使って少数のデータ点だけを計算し、残りの値は補間によって推定します。完全に正確とは言えませんが、十分に近い値が得られます。 つまり、ここでは計算コストの削減と手軽さが、補間誤差による損失を上回るというトレードオフが成立しているのです。 ベッ
-
C++で文字列内の文字のアルファベット値の合計からスコアを計算する方法
問題概要この問題では、文字列の配列 str[] が与えられ、配列内のすべての文字列の「スコア」を求めます。スコアは、文字列の位置(何番目にあるか)と、その文字列を構成する各文字のアルファベット値の合計との積として定義されます。ここでいうアルファベット値とは、「a=1、b=2、c=3 … z=26」というように、各英小文字に対応する番号のことです。入力例str[] = {learn, programming, tutorials, point}計算例「learn」は1番目 →sum = 12 + 5 + 1 + 18 + 14 = 50スコア = 50 × 1 = 50「programming」
-
C++で連結リストの交互ノードの合計を求める方法(反復法・再帰法)
問題概要 この記事では、連結リスト(リンクリスト)が与えられたときに、その交互ノード(0、2、4…番目のノード)の値の合計を求める方法を解説します。 連結リストとは、リンク(ポインタ)によって順次接続されたデータ構造の列です。各ノードはデータ本体と、次のノードを指す参照を持っています。 今回の課題は、連結リストのうち位置 0、2、4、6 … にあるノード、つまり先頭から1つおきのノードの値をすべて加算することです。 入出力例 入力: 4 → 12 → 10 → 76 → 9 → 26 → 1 出力: 24 説明: 交互ノードを取り出すと − 4 + 10 + 9 + 1 = 24 解決の考
-
C++で2からN/2までのすべての基数で表した数Nの桁の合計を求める方法
問題の概要この問題では、ある数値Nが与えられます。私たちのタスクは、2からN/2までのすべての基数で数値Nを表したときの、各桁の数字の合計を求めるプログラムを作成することです。つまり、数値を2からN/2までのすべての基数に変換する必要があります。例えば、n = 9の場合、基数は2、3、4となり、それぞれの基数における桁の合計をすべて足し合わせます。入出力例具体例を使って問題を理解しましょう。入力:N = 5出力:2説明:2からN/2までの基数は2のみです。 5を2進数で表すと「101」となり、桁の合計は 1+0+1 = 2 となります。解決アプローチこの問題を解くには、2からN/2までの各数値
-
【C++】arr[i] = i×(-1)^i となる配列で、インデックスLからRまでの要素の総和を求める方法
問題概要 この問題では、2つの整数 L と R が与えられます。また、arr[i] = i × (-1)i として定義される配列 arr[] を考えます。求めたいのは、この配列におけるインデックス L から R までの要素の総和です。 arr[i] は、インデックスが偶数のとき正の値、奇数のとき負の値になります。そのため、範囲 [L, R] 内の要素に対して「偶数インデックスは加算、奇数インデックスは減算」という処理を行った結果が答えとなります。 問題を理解するための具体例 入力: L = 2 , R = 6 出力: 4 説明: arr[] = {-1, 2, -3, 4, -5, 6} Su
-
C++で無向グラフの連結成分ごとの最小要素の合計を求める方法
この記事では、無向グラフのすべての連結成分に含まれる最小要素の合計を求める問題を、C++を使って解く方法を解説します。 問題の設定は次のとおりです。N個の整数からなる配列 arr が与えられ、arr[i] は (i+1) 番目のノードの値を表します。また、M個の辺のペア (u, v) が与えられ、それぞれノード u とノード v が辺で結ばれていることを示します。このとき、無向グラフの各連結成分ごとに最小値を求め、それらをすべて合計した値を出力するプログラムを作成します。なお、他のどのノードともつながっていないノードは、それ単独で1つの連結成分として扱います。 問題例 具体的な入力例で問題を確
-
C++で完全二分木の鏡像ノードの合計を中順走査で求める方法
問題概要この問題では、完全二分木が与えられます。目的は、中順(インオーダー)走査の順序で、完全二分木の鏡像ノードとの合計を求めるプログラムを作成することです。具体的には、まず左部分木を中順走査し、訪問した各ノードに対して、その鏡像にあたるノードの値を加算していきます。たとえば左側の葉ノードを走査しているときは、対応する右側の葉ノード(鏡像ノード)の値を足すというイメージです。押さえておきたい基本用語完全二分木(Complete Binary Tree)最後のレベルを除くすべてのレベルで、ノード数が最大になっている二分木のことです。中順走査(Inorder Traversal)木の走査手法の一つ
-
C++でN未満の2つの数の倍数の合計を求める方法
問題概要 この問題では、3つの整数 M1、M2、N が与えられます。求めるのは、N 未満に存在する M1 と M2 の倍数をすべて足し合わせた合計値です。 つまり、N 未満の数のうち、M1 または M2 の倍数に該当するものをすべて加算します。 問題を理解するための例 入力: N = 13, M1 = 4, M2 = 6 出力: 30 解説: 13 未満で 4 または 6 の倍数となる数は「4, 6, 8, 12」です。したがって合計は 4 + 6 + 8 + 12 = 30 となります。 解法1:シンプルな全探索アプローチ 最も基本的な解決策は、1 から N 未満まで順にループ処理を行い、M
-
C++でKで割った余りがRになる自然数(N以下)の合計を求める方法
問題概要この問題では、3つの数 N、K、R が与えられます。求めるのは、「N以下の自然数のうち、Kで割った余りがRになる数」の合計です。具体的には、i % K == R という条件を満たすN以下の数をすべて足し合わせます。例で理解しよう入力:N = 14, K = 4, R = 1出力:28説明: N以下の数のうち、4で割ると1余る数は 1, 5, 9, 13 です。これらを合計すると 1 + 5 + 9 + 13 = 28 となります。解法のアプローチこの問題を解くには、R から N まで、K ずつ増加させながらループします。こうすることで、条件を満たす数だけを効率的に取り出し、順に合計へ加
-
【C++】循環リンクリストのノード値の合計を求める方法
この記事では、循環リンクリスト(Circular Linked List)が与えられたときに、すべてのノードの値の合計を求めるプログラムをC++で作成する方法を解説します。 やるべきことはシンプルで、リンクリストを構成する全ノードの値を順番に読み取り、それらを加算していくだけです。 前提知識:重要な定義 リンクリストとは リンクリスト(連結リスト)とは、各データ(ノード)をポインタによるリンクで相互に接続したデータ構造の列です。配列と異なり、メモリ上の連続した領域を必要とせず、動的な挿入や削除に強いという特徴があります。 循環リンクリストとは 循環リンクリストはリンクリストの変形の一種で、先
-
C++で学ぶ循環キュー(リングバッファ)データ構造の実装方法
キュー(Queue)は、要素の集合を格納する抽象データ構造の一つです。キューはFIFO(First In, First Out:先入れ先出し)という仕組みを採用しており、最初に挿入された要素が最初に取り出されます。キューは線形データ構造として表現できますが、単純な配列で実装すると問題が発生する場合があります。挿入操作と削除操作を繰り返すうちに、先頭(front)と末尾(rear)の位置が配列の後方へ移動していきます。その結果、実際には空きスペースが残っているにもかかわらず、論理的な制約によって新しい要素を挿入できなくなることがあります。この問題を解決するために使われるのが循環キュー(Circu
-
C++のデキュー(両端キュー)と優先度付きキューの基本と使い方
キュー(Queue)は、FIFO(First In First Out:先入れ先出し)方式で動作するデータ構造として広く知られています。キューにはいくつかの派生形が存在し、その代表的なものが「デキュー(Dequeue:両端キュー)」と「優先度付きキュー(Priority Queue)」です。 デキュー(両端キュー)とは デキューは、文字どおり「両端からアクセスできるキュー(Double Ended Queue)」のことです。front(先頭)とrear(末尾)のポインタの組み合わせが2組あり、一方のペアは左側から、もう一方のペアは右側からキューを管理します。この構造では、両端のどちらからでも要
-
C++でソート済み配列を実装する方法:挿入・削除アルゴリズムを解説
この記事では、ソート済み配列(整列配列)に関する基本的な概念を解説します。配列は、同種のデータを連続したメモリ領域に格納するための均質なデータ構造です。データを利用する際に要素をソートする必要があるケースは多くありますが、最初から常にソートされた状態を保つ「ソート済み配列」を作成することも可能です。ここでは、ソート済み配列への要素の挿入(insert)と削除(delete)を行うアルゴリズムを紹介します。ソート済み配列に要素を挿入すると、その要素は自動的に適切なソート位置へ配置されます。そのため、挿入後に再度ソートを実行する必要はありません。また、削除を行う際は、まずバイナリサーチ(二分探索)
-
C言語の多次元配列とは?行優先・列優先の仕組みとサンプルコード
多次元配列とは配列とは、同種のデータ(ホモジニアスなデータ)をまとめて管理するための基本的なデータ構造です。配列の要素は、メモリ上の連続した領域に順番に配置されます。しかし実際のプログラミングでは、1次元の配列だけでは不十分なケースが少なくありません。例えば、表形式のデータや行列を扱う場合には、2次元配列やさらに多くの次元を持つ多次元配列を作成する必要があります。行優先方式と列優先方式多次元配列をメモリ上に表現する方法には、大きく分けて2つのアプローチがあります。ひとつは行優先(Row-Major)方式、もうひとつは列優先(Column-Major)方式です。r行 c列の2次元配列を考えてみま