-
C++で化学式を解析して各原子の個数を求める方法
問題概要 化学式が与えられたとき、そこに含まれる各原子(元素)の出現回数を求める問題を考えます。 元素名は必ず大文字アルファベットで始まり、その後に0個以上の小文字アルファベットが続きます。また、原子の個数が1より大きい場合は元素名の後ろに1桁以上の数字が付きますが、個数がちょうど1の場合は数字は省略されます。たとえば「H2O」や「H2O2」は有効な化学式ですが、「H1O2」は無効です。 たとえば、入力が「Na2(CO)3」であれば、出力は「C3Na2O3」となります。これは炭素(C)が3個、ナトリウム(Na)が2個、酸素(O)が3個含まれていることを意味します。 解き方のアプローチ この問
-
C++で特別なバイナリ文字列を辞書順最大に変換する方法
本記事では、「特別なバイナリ文字列」と呼ばれる特殊な性質を持つ文字列を、任意回数の操作によって辞書順で最大の文字列へと変換する問題を、C++を用いて解説します。特別なバイナリ文字列とはまず、対象となる「特別なバイナリ文字列」は、以下の2つの性質を満たします。文字列中の 0 と 1 の個数が等しい文字列の任意の接頭辞(先頭から始まる部分列)において、1 の出現数が常に 0 の出現数以上である問題の定義特別な文字列 S に対して行える「操作」は次のように定義されます。S から連続する2つの非空な特別な部分文字列を選び、それらを入れ替える。この操作を何度でも繰り返してよいとき、最終的に得られる文字列
-
C++で解く「カップルの手つなぎ」問題 ― 最小スワップ回数を求めるアルゴリズム
問題の概要 N組のカップルが、一列に並んだ2N個の座席に座っており、それぞれパートナーと隣り合って手をつなぎたいと考えています。すべてのカップルが隣同士に座る状態を作るために必要な、最小のスワップ(入れ替え)回数を求めましょう。 人と座席は0から2N-1までの番号で表されます。カップルには順に番号が割り当てられており、1組目は(0, 1)、2組目は(2, 3)、最後のN組目は(2N-2, 2N-1)というペアになります。 初期状態の着席情報は配列rowとして与えられ、row[i]にはi番目の座席に最初に座っている人の番号が入っています。 たとえば入力が [0, 2, 4, 1, 3, 5] の
-
C++でソート済み配列を作るための最大チャンク数を求める方法(Max Chunks To Make Sorted II)
整数の配列 arr が与えられたとき、この配列をいくつかの区間(パーティション)に分割し、それぞれの区間を個別にソートします。その後、各区間を連結すると、全体として1つのソート済み配列が得られます。このとき、作成できるパーティションの最大数はいくつになるでしょうか?例えば、入力が [3,2,4,5,5] の場合、出力は 4 になります。これは、[3,2]、[4]、[5]、[5] のように4つの区間に分割でき、それぞれをソートして連結すると [2,3,4,5,5] というソート済み配列が得られるからです。解法のアプローチこの問題は「左側からの最大値」と「右側からの最小値」を比較するというシンプル
-
C++でスライディングパズルを解く:BFSによる最短手数の求め方
スライディングパズルとは ここでは、2x3のボードを考えます。ボード上には1から5までの数字が書かれた5枚のタイルと、0で表される1つの空きマスがあります。 「移動」とは、空きマス(0)と、その上下左右に隣接する数字を入れ替える操作を指します。タイルが [[1,2,3],[4,5,0]] のように並んだとき、パズルは完成となります。 パズルの盤面が与えられたとき、完成状態にするために必要な最小の手数を求めます。どのように動かしても完成できない場合は -1 を返します。 例えば入力が [[1,2,3],[0,4,5]] の場合、出力は 2 になります。まず [0,4] を入れ替え、次に [0,5
-
C++で解く「レンガが落ちる」問題:ヒット時に落下するレンガの数を求める
問題概要 0と1で構成されるグリッドを考えます。値が1のセルはレンガを表しています。レンガが落下せずに安定していられるのは、次のいずれかの条件を満たす場合です。 そのレンガがグリッドの最上部に直接接している または、隣接する(上下左右の)レンガのうち、少なくとも1つが落下しない安定なレンガとつながっている このグリッドに対して、指定された順番で消去操作を行います。各操作では位置 (i, j) が与えられ、そこにレンガが存在すればそれが消滅し、その結果として他のレンガが連鎖的に落下することがあります。各消去操作の後に落下したレンガの数を、操作順に並べた配列を求めるのがこの問題のゴールです。
-
C++で最大の島を作る:DFSを使った効率的な解法と実装例
問題概要0と1から構成される2次元グリッドが与えられます。ここで、最大で1つの「0」を「1」に変更できるとします。その変更を行った後の、最も大きな島の面積を求めてください。なお、この問題における「島」とは、上下左右の4方向で隣接して連結された「1」のグループを指します。例えば、入力が [[1, 0], [0, 1]] の場合、出力は 3 となります。これは、どれか1つの「0」を「1」に変更することで2つの「1」がつながり、面積3の島が形成されるためです。解決アプローチこの問題は、DFS(深さ優先探索)を使って各島に一意のIDを割り当て、それぞれの島の面積をあらかじめ記録しておくことで効率よく解
-
C++で文字列のすべての部分文字列における一意な文字数の総和を計算する方法
まず、countUniqueChars(s) という関数を定義することを考えます。この関数は、文字列 s の中で一度だけ出現する文字(一意な文字)の個数を返します。たとえば s = HELLOWORLD の場合、「H」「E」「W」「R」「D」はそれぞれ1回しか現れないため、countUniqueChars(s) = 5 となります。本問題では、文字列 s が与えられたとき、そのすべての部分文字列 t に対する countUniqueChars(t) の総和を求めます。同じ部分文字列が複数回現れる場合でも、それぞれ別々にカウントする点に注意してください。答えは非常に大きな値になる可能性があるため
-
C++でレースの有利なスタート(ハンデ)を求めるプログラム
この問題では、100メートル競走において、走者Aが走者Bと走者Cにそれぞれ与えるハンデ(有利なスタート距離)を表す2つの整数が与えられます。ここでは、C++でレースのハンデを求めるプログラムの作成方法を解説します。問題の概要100メートル競走で、AがBに与えるハンデと、AがCに与えるハンデがそれぞれ分かっているとします。このとき求めたいのは、BがCに与えるべき相対的なハンデです。「AがBにハンデとしてXメートル与える」とは、Aが100メートル完走する間に、Bは(100 − X)メートルだけ走ればよいという意味です。つまり、Bはその分だけゴールに近い位置からスタートできることになります。入力例1
-
C++で解く長方形エリアII ― 座標圧縮と走査線法による被覆面積の計算
問題概要 軸に平行な長方形のリストが与えられるものとします。各 rectangle[i] = {x1, y1, x2, y2} において、(x1, y1) は i 番目の長方形の左下隅の座標、(x2, y2) は右上隅の座標を表します。 求めたいのは、平面上でこれらすべての長方形が覆っている領域の合計面積です。答えは非常に大きな値になる可能性があるため、109 + 7 で割った余りを返すことになっています。 たとえば、入力が次のような場合を考えてみましょう。 このとき、出力は 6 となります。 解法の方針:座標圧縮+走査線(スイープライン) この問題は、座標圧縮(座標の離散化)と走査線法(
-
C++で配列の隠し数(ヒドゥンナンバー)を求めるプログラムの作成方法
この問題では、n個の整数値で構成される配列 arr[] が与えられます。求めるのは、C++で配列の隠し数(ヒドゥンナンバー)を見つけるプログラムです。問題の説明隠し数とは、配列の各要素からその数を引いたとき、差の合計がちょうど0になるような数のことを指します。具体例で問題を確認しましょう。入力arr[] = {4, 1, 6, 7, 2}出力4説明: 配列のすべての要素から4を引き、その値を合計すると以下のようになります。= (1 - 4) + (6 - 4) + (7 - 4) + (2 - 4)= -3 + 2 + 3 - 2 = 0このように合計が0になるため、4がこの配列の隠し数である
-
C++で正多角形の内角と外角を求めるプログラム
本記事では、正多角形の辺の数 n が与えられたとき、その正多角形の内角と外角を求めるC++プログラムを紹介します。 問題の概要 与えられた辺の数 n に対して、その正多角形を構成する各内角と各外角の値を計算します。 内角とは 内角とは、多角形の隣り合う2つの辺が作る角のうち、多角形の内側にある角のことです。 外角とは 外角とは、多角形の隣り合う2つの辺が作る角のうち、多角形の外側にある角のことです。 入出力例 具体例を使って問題を確認してみましょう。 入力 n = 5 出力 内角 = 108 外角 = 72 五角形(n = 5)の場合、内角は108度、外角は72度になります。 解法のアプローチ
-
【C++】名前からイニシャルを抽出するプログラムの作成方法
このプログラムでは、人物の名前を表す文字列 name が与えられます。私たちの課題は、C++を使ってその名前からイニシャル(頭文字)を抽出するプログラムを作成することです。 コードの概要 − 文字列として渡された名前の中から、各単語の頭文字だけを取り出して表示します。 問題を理解するための具体例を見てみましょう。 入力 name = ram kisan saraswat 出力 R K S 説明 名前に含まれるすべての単語の最初の文字を抽出し、それらをイニシャルとして出力します。上記の例では、「ram」「kisan」「saraswat」という3つの単語それぞれの頭文字「R」「K」「S」が結果と
-
C++で解く「すべての鍵を取得する最短経路」問題:BFSとビットマスクの活用法
問題の概要グリッド上で展開されるパズル問題を考えます。グリッドには以下の記号が使われています。. … 空きマス(自由に移動可能)# … 壁(通行不可)@ … スタート地点a, b, c … … 鍵(マスを通過すると自動的に拾う)A, B, C … … 鍵穴(ロック)。対応する鍵を持っていないと通過できないスタート地点から出発し、1回の移動で上下左右4方向のいずれかに1マス進みます。グリッドの外に出ることはできず、壁が進路を妨げます。鍵のマスを通過するとその鍵を拾い、対応する鍵を所持していない限りロックのマスは通れません。鍵穴「A」には鍵「a」、鍵穴「B」には鍵「b」のように、大文字がロック、同
-
C++で文字列を復号化してk番目の文字を求めるプログラムの作成方法
はじめに このチュートリアルでは、C++を使って「文字列を復号化した後にk番目の文字を見つける」プログラムについて詳しく解説します。 この問題では、英字と数字が混在した文字列と整数Kが与えられます。文字列中の数字は、それまでに読み取った部分の繰り返し回数を表しています。私たちのタスクは、与えられた文字列を復号化し、復号後の文字列におけるK番目の位置にある文字を特定することです。 アプローチ 復号化後の文字列は元の文字列よりも桁違いに長くなる可能性があるため、実際に文字列をメモリ上に展開してしまうのは非効率です。そこで本記事では、復号後の「長さ」だけを追跡することで、省メモリかつ高速に答えを導く
-
C++で文字列内の最大・最小のASCII値を持つ文字を検索するプログラム
問題概要 この問題では、1つの文字列が与えられます。私たちのタスクは、C++を使って、文字列内のASCII値が最も大きい文字と最も小さい文字を検索するプログラムを作成することです。 コードの説明 − ここでは、大文字と小文字の両方を含む文字列が与えられており、その中からASCII値が最大の文字と最小の文字を見つけ出す必要があります。 問題を理解するために、具体的な例を見てみましょう。 入力 str = TutorialsPoint 出力 Largest = u、Smallest = P 説明 ASCII値の規則では、大文字は小文字よりも小さい値を持ちます。 したがって、大文字の中で最小の「A」
-
C++の三項演算子で最大値を求める方法|2つ・3つ・4つの数値に対応したサンプルコード
この記事では、与えられた複数の数値の中から最大値を求めるC++プログラムを、三項演算子(条件演算子)だけを使って実装する方法を解説します。 扱う数値のパターンは次の3種類です。 2つの数値 3つの数値 4つの数値 コードの説明 ここでは、2つ・3つ・4つのいずれかの個数で数値が与えられ、三項演算子を活用してその中の最大の要素を見つけます。if文や標準ライブラリのmax関数などは使わず、三項演算子の組み合わせだけで条件分岐を実現するのがポイントです。 具体例で問題のイメージをつかみましょう。 2つの数値 入力: 4, 54 出力: 54 3つの数値 入力: 14, 40, 26 出力: 40
-
C++でシーケンスにスタンプを押して目標文字列を作る方法
問題の概要小文字だけで構成された目標文字列(target)を作りたいと考えます。初期状態では、目標文字列と同じ長さ n の「?」が並んだ列しかなく、これとは別に小文字からなるスタンプ(stamp)が1つ与えられています。各ターンでは、この列の上にスタンプを重ね、その範囲の文字をスタンプの対応する文字で置き換えることができます。ターン数は最大でも 10 × n 回までです。例えば、初期状態が「?????」でスタンプが「abc」なら、最初のターンで作れるのは「abc??」「?abc?」「??abc」のような文字列です。列がスタンプの組み合わせで作れる場合は、各ターンでスタンプを押した位置(左端の文
-
C++で条件演算子・ビット演算子を使わずに4つの数値の最大値を求める方法
問題の概要この問題では、4つの整数が与えられます。求められているのは、C++において条件演算子(三項演算子)やビット演算子を一切使わずに、これら4つの数値の中から最大値を見つけるプログラムを作成することです。コードの説明ここでは4つの整数値が与えられており、if文などの条件分岐やビット操作に頼らずに、その中から最大値を特定する必要があります。問題を理解するための例入力a = 4, b = 7, c = 1, d = 9出力9解決アプローチこの問題を解くには、まず2つの要素を取り出し、ペアの中で大きい方を選んでいきます。各ペアに対して2要素の配列 arr[] を作成し、ブール値を使ってどちらの要
-
C++で行列(マトリックス)内の最大要素を求めるプログラム
この問題では、n×m のサイズを持つ行列(マトリックス)が与えられます。C++を使って、行列の中から最大の要素を見つけるプログラムを作成するのが課題です。 問題の説明 やるべきことはシンプルで、行列に含まれる要素の中から最も大きな値を求めるだけです。 それでは、具体的な例を使って問題を理解しましょう。 入力例 mat[3][3] = {{4, 1, 6}, {5, 2, 9}, {7, 3, 0}} 出力例 9 解き方のアプローチ この問題の解法は非常にシンプルで、行列全体を走査するだけです。具体的には、二重のforループを使って行列の各要素を順番に調べ、各要素が現在の最大値 maxVal よ