-
C++のファイルオープンモード徹底解説:「r」と「r+」の違いとは?
プログラミングにおいて、ファイル操作はメモリとのやり取りを通じてファイルへアクセスし、データを取得・保存するために非常に重要な機能です。 プログラムを使えば、ファイルからデータを読み取るだけでなく、ファイルへのデータの書き込みなど、さまざまな処理を実行できます。 この記事では、その中でも「ファイルからのデータ読み込み」に焦点を当てて解説します。 ファイル操作の基本:オープンモードとは プログラミングでは、何らかの操作を行う前に必ず対象のファイルを「開く(オープンする)」必要があります。そして、ファイルを開く際には複数の「モード」が用意されており、どのモードで開いたかによって、そのファイルに対
-
C++で隣接要素を埋める最小反復回数により配列を1で満たす方法
この問題では、0または1のいずれかで構成されるn個の要素を持つ配列arrが与えられます。求められているのは、「隣接要素を埋める」という操作を最小の反復回数で実行し、配列全体を1で満たすことです。 例で問題を理解する 入力:arr[] = {0, 1, 1, 0, 0, 1} 出力:1 この場合、インデックス3〜4に連続する2つの0は、両側の1から同時に伝播することで1回の反復で埋められるため、答えは1となります。 解法アプローチ この問題を解くうえで重要なのは、「ある位置に1が存在すれば、その両隣の2つの0を1に変換できる」という性質です。 もし arr[i] が 1 ならば、arr[i-1
-
C++で親配列で表現された二分木の高さを求める方法
この問題では、木構造を表すサイズ n の配列 arr[] が与えられます。ここでの課題は、親配列で表現された二分木の高さを求めることです。 二分木とは、各ノードが最大2つの子ノードを持つことができる木構造のデータ構造です。本問題では、配列の各要素 arr[i] が「インデックス i のノードの親ノードのインデックス」を意味し、根ノードのみ arr[i] = -1 として表されます。 木の高さとは、根ノードから最も遠い葉ノードまで移動する際に通過するノードの数のことです。 解決アプローチ この問題に対する単純な解決策は、親配列から木を実際に構築する方法です。まず木の根を特定し、そのインデックス
-
C++で数値がリスト内のすべての数値で割り切れるかどうかを判定する方法
問題概要この問題では、n個の数値からなるリストと、1つの数値が与えられます。私たちのタスクは、リスト内のすべての数値が指定された数値で割り切れるかどうかを判定することです。具体的には、リストのすべての要素が与えられた数値(num)で割り切れるかどうかを確認します。例で問題を理解しましょう入力: list[] = [4, 10, 6, 5, 9]、num = 5出力: No説明:要素 4、6、9 は 5 で割り切れません。解決アプローチこの問題を解くには、リストの各要素を順番に調べ、num で割り切れるかどうかを確認します。リスト内のすべての数値が num で割り切れる場合は true を返し、
-
【C++】文字列が指定した別の文字列で始まり、かつ終わっているかを判定する方法
問題概要この記事では、2つの文字列 str と conStr が与えられたときに、「文字列 str が conStr で始まり、かつ conStr で終わっているか」を判定する方法を解説します。入出力例入力: str = abcprogrammingabc、conStr = abc出力: Trueこの例では、文字列 str は先頭も末尾も abc で始まっており、条件を満たすため True が出力されます。解決アプローチこの問題を解くための手順は以下のとおりです。まず、str と conStr のそれぞれの長さを求めます。もし str の長さが conStr の長さより短い場合は、接頭辞・接尾
-
【C++】配列内に「全要素の合計の半分」と等しい要素が存在するか判定する方法
この記事では、ソート済みの重複なし整数配列 arr が与えられたとき、その配列の中に「全要素の合計値の半分」に等しい要素が存在するかどうかを判定する問題を解説します。問題の概要配列 arr[] から、次の条件を満たす要素 x を見つけることが目的です。配列全体の要素の合計 = 2 × x(つまり、x は合計値のちょうど半分)具体例で理解しよう入力: arr[] = {2, 4, 5, 6, 7}出力: No(該当する要素なし)解説:合計 = 2 + 4 + 5 + 6 + 7 = 2424 の半分は 12 ですが、配列内に 12 という要素は存在しないため、該当する要素はありません。解法のアプ
-
C++で与えられた行列がテプリッツ行列かどうかを判定する方法
問題の概要 この記事では、サイズ n×n の2次元正方行列 mat[][] が与えられたとき、その行列がテプリッツ(Toeplitz)行列であるかどうかを判定する方法を解説します。 テプリッツ行列とは? テプリッツ行列とは、左上から右下に向かうすべての斜め線(対角線)上の要素が同じ値になる行列のことです。数式で表すと、任意の i, j に対して次の関係が常に成り立ちます。 mat[i][j] == mat[i+1][j+1] 具体例で理解しよう 入力: Mat[][] = {{6, 7, 8, 9}, {4, 6, 7, 8}, {1, 4, 6,
-
C++で与えられた数が最初のn個の自然数の和かどうかを判定する方法
この問題では、ある数値 num が与えられ、それが最初の n 個の自然数の和になっているかどうかを判定します。問題の説明与えられた数が、1から始まる連続する自然数(1+2+3+…+n)の総和として表せるかどうかを確認し、表せる場合はその n の値を求めます。入出力例で問題を理解しよう入力:num = 55出力:yes, 10説明:55 は最初の 10 個の自然数の和、つまり 1+2+3+4+5+6+7+8+9+10 に一致します。解法アプローチ①:累積和によるシンプルな方法最も単純なアプローチは、n を 1 から順に増やしながら自然数の和を計算し、その値が num と等しくなるか、num を超
-
C++でページを指定した角度で回転できるかどうかを判定する方法
この問題では、ページ上にある3つの点 x、y、z の座標が与えられます。私たちのタスクは、ページをある角度で回転させることが可能かどうかを判定することです。ここでの回転とは、「x」の新しい位置が元の「y」の位置に移り、「y」の新しい位置が元の「z」の位置に移るような回転を指します。そして、回転の可否に応じて「Yes」または「No」を出力します。問題を理解するための具体例入力:x = (0, 1), y = (1, 0), z = (0, -1)出力:Yes説明:この場合、ページを90度回転させることで、条件を満たす配置を実現できます。解法のアプローチページをある角度で回転できるかどうかは、次の
-
【C++】到着時刻・出発時刻が与えられたとき、k部屋の予約がすべて成立するか判定する方法
この問題では、ホテルへの到着時刻と出発時刻を表す N 個の値からなる2つの配列と、整数 k が与えられます。求めるのは、k 部屋のホテルですべての予約(到着・出発)を受け入れられるかどうかの判定です。問題の概要ホテルには k 室しかありません。そのため、複数の予約の滞在期間が重なり、同時に必要となる部屋数が k を超える場合は予約をすべて受け入れることができません。逆に、どの時点でも必要な部屋数が k 以内に収まるのであれば、すべての予約は成立します。入出力例入力:Arrivals : {1, 4, 5, 7} Departures : {3, 5, 6, 9} K = 1出力:Yesこの
-
【C++】ルートからリーフへの経路上に、合計がルートの値と一致するノードのペアが存在するか判定する方法
この問題では、二分木(Binary Tree)が与えられます。求められているのは、「ルートからリーフ(葉)に至る経路上に、2つのノードの値の合計がルートのデータと等しくなるペアが存在するかどうか」を判定することです。つまり、ルートノードからリーフノードまでの間にあるノードの中から2つを選んだとき、その値の合計がルートノードの値と一致するような組み合わせが存在するかをチェックします。問題例で理解しよう入力:出力: Yes説明:ルートノードの値は 7 です。合計が7になるペアとして、(2, 5) と (1, 6) が存在します。解決アプローチ:ハッシュを活用した探索木を走査しながら、ハッシュセット
-
C++で合計が0となる部分配列の存在を効率的に判定する方法
はじめに この記事では、整数値からなるサイズ n の配列 arr[] が与えられたときに、合計が0となる部分配列(サブアレイ)が存在するかどうかを判定する方法を解説します。 具体的には、配列の中に「すべての要素の合計が0に等しい」連続した部分配列が含まれているかどうかを確認する問題です。 問題の例 入力: arr[] = {3, 1, -2, 1, 4, 5} 出力: Yes 説明: 部分配列 {1, -2, 1} の要素の合計は 1 + (-2) + 1 = 0 となり、条件を満たしています。このため答えは「Yes」となります。 解法アプローチ 1. 素朴な解法(全探索) 最もシンプルな
-
【C++】-1と+1からなる配列に、合計が0となるサイズKの部分集合が存在するか判定する方法
この問題では、1と-1のみから構成される配列 arr[] と整数値 k が与えられます。私たちのタスクは、-1と+1からなる配列の中に、合計が0となるサイズKの部分集合が存在するかどうかを判定することです。問題例で理解しよう入力: arr[] = {-1, 1, -1, -1, 1, 1, -1}, k = 4出力: YES説明:サイズ4の部分集合 {-1, 1, -1, 1} を選ぶと、合計 = -1 + 1 - 1 + 1 = 0 となります。解法の考え方まず、合計が0になるサイズKの部分集合が存在するかどうかを確認する必要があります。部分集合には配列の任意の要素を選べるため、部分集合内に
-
C++で同じジャンプ回数の後に2人が出会えるかどうかを判定する方法
問題概要 この問題では、2人のスタート地点と1回あたりのジャンプ距離を表す4つの整数が与えられます。求めるのは、同じジャンプ回数の時点で2人が同じ位置に出会うことができるかどうかの判定です。 具体的には、それぞれ点p1とp2からスタートし、1回のジャンプでj1とj2だけ進む2人が、ジャンプを繰り返す過程のどこかで同じ位置に到達しうるかを確認します。 例で理解しよう 入力: p1 = 5, p2 = 9, j1 = 4, j2 = 2 出力: Yes 説明: 1回目のジャンプ後: p1 = 9、p2 = 11 2回目のジャンプ後: p1 = 13、p2 = 13 2回目のジャンプの後、両者が
-
C++でソート済み配列に含まれる余分な要素のインデックスを見つける方法
この問題では、サイズ n と n+1 の2つのソート済み配列 arr1 と arr2 が与えられます。両配列の要素は、余分な要素を除いてすべて同じです。私たちのタスクは、ソート済み配列の一方に存在する余分な要素のインデックスを見つけることです。 問題の説明: サイズ n+1 の配列に存在し、サイズ n の配列には存在しない要素のインデックスを求める必要があります。 問題を理解するための例 入力: arr1[n] = {3, 5, 7, 8, 9, 12} arr2[n+1] = {3, 4, 5, 7, 8, 9, 12} 出力: 1 説明: 値が 4 の要素が余分な要素であり、そのイン
-
C++で配列の要素を最も多く割り切る整数を見つける方法
問題の概要 この問題では、n個の整数からなる配列 arr[] が与えられます。 私たちの課題は、配列の要素を最も多く割り切る整数を見つけることです。 問題の説明: 配列の要素を最大数だけ割り切ることができる数 p を求める必要があります。該当する数が複数存在する場合は、より小さい方の値を返します。 具体例で理解しよう 入力: arr[] = {4, 5, 6, 7, 8} 出力: 2 説明: 数値 2 は {4, 6, 8} の3つの要素を割り切ることができます。つまり、配列の中で最も多くの要素を割り切るのは 2 というわけです。 解法のアプローチ 1. 単純な全探索 最もシンプルな解決策は
-
C++で値が最も小さいK個のアイテムを検索する方法
この記事では、アイテム名とその値からなるリストと整数 k が与えられたときに、値が最も小さい K 個のアイテムを見つける方法について解説します。問題の概要与えられたリストの中から、値が最も小さい k 個のアイテムを取り出すことが目的です。具体例で問題を理解しよう入力: item-value = { {item1, 200}, {item2, 100}, {item3, 500}, {item4, 400} }、k = 2出力: item1、item2説明:値が最も小さい2つの要素は、値200の item1 と値100の item2 です。解法アプローチこの問題は、貪欲法(グリーディ法)によって
-
C++で配列の上位k個の最大要素を元の順序で出力する方法
問題概要この問題では、n個の要素からなる配列 arr[] が与えられます。目的は、配列の中で値の大きい方からk個の要素を取り出し、元の配列での登場順序どおりに出力することです。ポイントは、単に値の大きい順に並べるのではなく、元のインデックスの順番を維持したまま表示するという点にあります。入出力例入力: arr[] = {5, 1, 3, 6, 2}, k = 2出力: 5, 6解説: 配列内で最も大きい2つの要素は「6」と「5」ですが、元の配列では「5」が「6」よりも先に現れるため、この順序で出力されます。解法のアプローチこの問題は、次の手順で解くことができます。元の配列 arr[] をコピー
-
C++で指定されたn個の範囲からk番目に小さい要素を検索する方法
問題の概要この問題では、n個の数値範囲と整数kが与えられます。これらの範囲に含まれるすべての整数を結合してできる配列の中から、k番目に小さい要素を見つけることが課題です。具体的には、各範囲内のすべての整数を集めて昇順に並べた配列を作成し、その中のk番目の値を求めることになります。問題例入力:ranges = {{2, 5}, {7, 9}, {12, 15}}, k = 9出力:13説明:作成される配列は {2, 3, 4, 5, 7, 8, 9, 12, 13, 14, 15} となります。この配列を小さい順に数えると、9番目に小さい要素は13です。解決アプローチ最もシンプルな解法は、すべて
-
C++で連結リストの中央から先頭に向かってk番目のノードを検索する方法
問題概要この問題では、連結リスト(Linked List)と数値kが与えられます。求めるのは、連結リストの中央ノードから先頭(Head)に向かってk番目にあるノードです。具体例を使って問題を確認してみましょう。入力: 連結リスト: 4 → 2 → 7 → 1 → 9 → 12 → 8 → 10 → 5、k = 2出力: 7解説:まず、中央ノードの値は 9 です。そして、中央から先頭に向かって2番目のノードは 7 になります。解法のアプローチ連結リストの中央から先頭に向かってk番目の要素を見つけるには、まずリストを先頭から末尾まで一度走査し、ノードの総数nを求めます。すると、中央から先頭に向かっ