C++

 Computer >> コンピューター >  >> プログラミング >> C++
  1. C++で文字列を単調増加にするための最小反転回数を求める方法

    問題の概要0と1のみから構成される文字列が与えられたとします。この文字列が「単調増加」であるとは、いくつかの0(0個でも可)の後に、いくつかの1(これも0個でも可)が続く形になっている状態を指します。ここで、0と1からなる文字列Sが与えられ、任意の0を1に、または1を0に反転(フリップ)できるものとします。このとき、Sを単調増加な文字列にするために必要な最小の反転回数を求めるのが本問題です。例えば、入力が「010110」の場合、出力は2になります。反転を2回行うことで、「011111」または「000111」という単調増加な文字列を得ることができるためです。解法のアプローチこの問題は、貪欲法(グ

  2. C++で合計がSとなるバイナリ部分配列を数える方法

    0と1のみから構成される配列Aが与えられたとき、合計がSとなる空でない(非空の)部分配列がいくつ存在するかを求める問題です。例えば、入力が [1,0,1,0,1]、S = 2 の場合、答えは 4 になります。該当する部分配列は [1,0,1]、[1,0,1,0]、[0,1,0,1]、[1,0,1] の4つです。解法のアプローチこの問題は「スライディングウィンドウ(尺取り法)」を用いた補助関数 atMost() を使うことで効率的に解けます。atMost(A, x) は「合計が x 以下となる部分配列の個数」を返す関数です。すると、合計がちょうど S となる部分配列の個数は、次の差として求められ

  3. C++で解く「美しい配列」問題:等差条件を回避する順列の構築アルゴリズム

    固定した値 N に対して、配列 A が「美しい(beautiful)」とは、A が 1, 2, ..., N の順列であり、かつ次の条件を満たすことを意味します。 任意の i < j について、i < k < j を満たし、かつ A[k] * 2 = A[i] + A[j] となる k は存在しない。 言い換えると、インデックスの順序において、両端の要素の平均値が中央の要素と一致するような3つの要素の組み合わせが一切現れてはいけない、という制約です。N が与えられたとき、この条件を満たす美しい配列 A を1つ構築するのが本問題の目的です。 たとえば入力が 5 の場合、出力

  4. C++で配列の要素をすべて一意にするための最小増加操作回数を求める方法

    問題の概要整数の配列 A が与えられます。ここでいう「1回の操作」とは、任意の A[i] を選び、その値を 1 だけ増やすことです。この操作を繰り返して、配列 A のすべての値を一意(重複なし)にするために必要な最小の操作回数を求めます。例えば、入力が [3,2,1,2,1,7] の場合、出力は 6 になります。6 回の操作を行うと、配列は [3,4,1,2,5,7] となり、すべての値が異なる状態にできます。一方、5 回以下の操作ではすべての値を一意にすることができないことが示せます。解法のアプローチこの問題は、ソートと貪欲法(グリーディ法)を組み合わせることで効率的に解くことができます。手

  5. C++で解く「トークンのバッグ」問題:貪欲法による最大スコアの求め方

    問題の概要初期パワー P と初期スコア 0 点を持った状態で、トークンの入った袋が 1 つ与えられます。各トークンには値 token[i] が割り当てられており、それぞれ最大 1 回しか使用できません。トークンの使い方には、次の 2 通りがあります。現在のパワーが token[i] 以上の場合、トークンを表向きにプレイできます。パワーを token[i] 消費し、その代わりにスコアを 1 点獲得します。現在のスコアが 1 点以上ある場合、トークンを裏向きにプレイできます。スコアを 1 点失う代わりに、パワーを token[i] 獲得します。この問題では、任意の数のトークンを使用した後に到達でき

  6. C++で解く!カードを昇順に公開するデッキの並べ方

    一意の番号が書かれたカードで構成されるデッキがあるとします。デッキは任意の順序に並べ替えることができ、最初はすべてのカードが裏向き(未公開)の状態で1つの山になっています。ここで、すべてのカードが公開されるまで、以下の手順を繰り返し実行します。デッキの一番上のカードを取り出して公開し、デッキから取り除きます。まだデッキにカードが残っている場合は、次の一番上のカードをデッキの一番下へ移動します。未公開のカードが残っている場合は手順1に戻ります。そうでなければ処理を終了します。求めるのは、この操作を行ったときにカードが昇順で公開されるようなデッキの並び順です。答えの最初の要素はデッキの一番上とみな

  7. C++で解く「2倍ペアに並べ替えられるか」判定アルゴリズム

    問題概要長さが偶数の整数配列 A が与えられます。この配列を並べ替えることで、すべての 0 <= i < len(A) / 2 について A[2 * i + 1] = 2 * A[2 * i] が成り立つようにできる場合のみ true を返します。例えば、入力が [3, 1, 3, 6] の場合は false を返し、[4, -2, 2, -4] の場合は true を返します。後者は [-2, -4] と [2, 4] というペアに分けられるためです。解き方の考え方この問題は、各要素の出現回数を記録したマップ(連想配列)を使って、小さい値から順に「自分の2倍の値」とマッチングさせていくことで

  8. C++で解く「N日後の監獄の独房」問題:14日周期を利用した効率的な解法

    問題の概要8つの独房が一列に並んでおり、各部屋には囚人が収容されているか、空室であるかのどちらかだとします。毎日、各部屋の占有状態は以下のルールに従って変化します。ある部屋の両隣が、どちらも占有されている(またはどちらも空室である)場合 → その部屋は翌日占有状態になります。それ以外の場合 → その部屋は翌日空室になります。監獄の現在の状態は配列で表現します。i番目の部屋が占有されていれば cells[i] は 1、空室なら 0 となります。監獄の初期状態と日数 N が与えられたとき、N日後の監獄の状態を求めるのがこの問題の目的です。具体例入力が [0,1,0,1,1,0,0,1]、N = 7

  9. C++で解く「最大幅ランプ」問題 ― 単調スタックによるO(n)アルゴリズム

    問題概要 整数の配列 A が与えられます。「ランプ」とは、i < j かつ A[i] <= A[j] を満たすインデックスの組 (i, j) のことを指し、その幅は j − i で定義されます。求めたいのは、配列 A の中で幅が最大となるランプの幅です。条件を満たすランプがひとつも存在しない場合は 0 を返します。 たとえば入力が [6, 0, 8, 2, 1, 5] の場合、答えは 4 になります。(i, j) = (1, 5) を選べば A[1] = 0 ≤ A[5] = 5 が成立し、幅は 5 − 1 = 4 となるためです。 アプローチ:単調スタック すべての組み合わせを

  10. C++で隣り合う桁の差が同じ数をすべて求めるアルゴリズム

    問題概要長さ N の非負整数のうち、「隣り合う 2 つの桁の絶対差がすべて K に等しい」という条件を満たす数をすべて求めることを考えます。ただし、答えに含まれる各数値は、数値 0 自体を除いて先頭に 0 を付けてはいけません。また、答えは任意の順序で返して構いません。例として、N = 3、K = 7 の場合、出力は [181, 292, 707, 818, 929] となります。ここで 070 は先頭に 0 が付いているため、有効な数とはみなされない点に注意してください。解法のアプローチこの問題は、桁を 1 桁ずつ伸ばしながら候補を段階的に構築していく動的計画法(DP)的な手法で効率よく解く

  11. C++で最長乱流部分配列を求める方法【動的計画法による解説】

    配列 A の部分配列 A[i], A[i+1], ..., A[j] が「乱流(turbulent)」であるとは、次のいずれかの条件を満たすことを意味します。 i ≤ k < j に対して、k が奇数のときは A[k] > A[k+1]、k が偶数のときは A[k] < A[k+1] または、i ≤ k < j に対して、k が偶数のときは A[k] > A[k+1]、k が奇数のときは A[k] < A[k+1] つまり、隣接する要素同士の大小関係が、部分配列全体にわたって交互に入れ替わっている状態が「乱流」です。本記事では、配列 A から最大サイズ

  12. C++で実装する時間ベースのKey-Valueストア(TimeMap)の解説

    時間ベースのKey-Valueストアとは 本記事では、時間ベースのKey-Valueストアである「TimeMap」クラスをC++で実装する方法を解説します。TimeMapは、次の2つの操作をサポートするデータ構造です。 set(string key, string value, int timestamp):キーと値を、指定されたタイムスタンプとともに保存します。 get(string key, int timestamp):以前に呼び出された set(key, value, timestamp_prev) のうち、timestamp_prev <= timestamp を満たす値を返

  13. C++で「aaa」「bbb」を含まない文字列を生成するアルゴリズム

    問題の概要2つの整数 A と B が与えられたとき、以下の条件をすべて満たす文字列 S を返すことを考えます。文字列 S の長さは A + B であり、文字 a がちょうど A 個、文字 b がちょうど B 個含まれていること部分文字列として「aaa」および「bbb」が文字列 S 内に一切現れないことたとえば、A = 4、B = 1 が与えられた場合、答えは「aabaa」となります。解き方(アプローチ)この問題は貪欲法(グリーディー法)で効率的に解くことができます。数の多い文字を2個ずつペアで使い、そのあとに数の少ない文字を1個挟むことで、差を徐々に縮めていくのがポイントです。具体的には、以下

  14. 【C++】等式方程式の充足可能性問題をUnion-Findで解く方法

    問題概要変数間の関係を表す方程式の配列が与えられます。各文字列 equations[i] は長さ4で、「a==b」または「a!=b」という2つの形式のいずれかを取ります。ここで a と b は小文字のアルファベット1文字からなる変数名を表します。求めるのは、与えられたすべての方程式を満たすように各変数に整数を割り当てることが可能かどうかです。可能な場合にのみ true を返します。例えば、入力が [a==b,b==c,a==c] の場合、3つの変数すべてに同じ値を割り当てればよいため、答えは true になります。アプローチ:Union-Find(素集合データ構造)この問題は、Union-Fi

  15. C++で解く「最高の観光ペア」問題:効率的なアルゴリズムと実装

    問題の概要正の整数からなる配列 A が与えられ、A[i] は i 番目の観光スポットの価値を表しているものとします。2つの観光スポット i と j の間の距離は j - i で定義され、観光スポットのペア(i < j)のスコアは次の式で計算されます。A[i] + A[j] + i − jこのとき、すべてのペアの中で最大のスコアを求める必要があります。たとえば、入力が [8, 1, 5, 2, 6] の場合を考えてみましょう。i = 0、j = 2 を選ぶと、A[0] + A[2] + 0 − 2 = 8 + 5 + 0 − 2 = 11 となり、これが最大スコアになります。したがって出力

  16. 【C++】バイナリ文字列に1〜Nの2進表現がすべて部分文字列として含まれるか判定する方法

    問題概要 バイナリ文字列 S と正の整数 N が与えられたとします。1 から N までのすべての整数 X について、その 2 進表現が文字列 S の部分文字列として含まれる場合に限り true を返すのが目的です。 例えば、S = 0110、N = 3 のケースを考えてみましょう。1 の 2 進表現は 1、2 は 10、3 は 11 であり、これらはいずれも 0110 の中に含まれています。したがって、この場合は true が返ります。 解法のアプローチ この問題は、次の手順で解くことができます。 整数 n を受け取り、その 2 進表現を文字列として返す convert() メソッドを定義

  17. C++で整数を負の2進数(Base -2)に変換する方法

    問題の概要ある整数 N が与えられたとき、「0」と「1」だけから構成される文字列で、その値を負の2進数(基数 -2)で表現することを考えます。ただし、返す文字列の先頭に余分なゼロを付けてはいけません。例外として、値がちょうど 0 の場合は「0」を返します。例えば、入力が 2 の場合、出力は「110」になります。これは次のように計算できます。1 × (-2)^2 + 1 × (-2)^1 + 0 × (-2)^0 = 4 − 2 + 0 = 2解法のアプローチ通常の2進数変換と似ていますが、基数が負であるため、剰余が負になった場合の処理がポイントになります。以下の手順で解きます。結果を格納する空

  18. C++でエンクレーブ(飛び地)の数を求めるアルゴリズム

    問題概要2次元配列 A が与えられます。各セルは 0(海)または 1(陸)を表しています。ここでの「移動」とは、ある陸のマスから上下左右(4方向)に隣接する別の陸のマスへ歩くこと、あるいはグリッドの境界の外へ出ることを指します。求めたいのは、「どれだけ移動を繰り返してもグリッドの境界外へ出ることができない」陸のマスの個数です。例えば、次のようなグリッドが与えられたとします。0000101001100000この場合、答えは 3 になります。0 に完全に囲まれた 1 が 3 つ存在し、残りの 1 つは境界に接しているため囲まれていないからです。解法のアプローチこの問題は DFS(深さ優先探索)を使

  19. C++で解くビデオステッチング問題:区間[0, T]をカバーする最小クリップ数の求め方

    問題概要長さT秒のスポーツイベントを撮影した複数のビデオクリップがあるとします。これらのクリップは互いに重なり合っており、長さもさまざまです。各クリップclips[i]は1つの区間を表し、時刻clips[i][0]に始まり、時刻clips[i][1]に終わります。クリップは自由に切断できます。ここで求めたいのは、イベント全体の区間[0, T]を完全にカバーできるようにクリップを切り貼りするために必要な最小のクリップ数です。カバーが不可能な場合は-1を返します。例えば、入力が[[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]]、T = 10の場合、答えは3になります。クリ

  20. C++で最長の等差部分列を求めるアルゴリズムを解説

    問題の概要整数の配列 A が与えられたとき、A に含まれる「最長の等差部分列」の長さを返すことを考えます。まず用語を確認しましょう。配列 A の部分列とは、A[i_1], A[i_2], ..., A[i_k](0 <= i_1 < i_2 < ... < i_k <= A.length - 1)のように、元の配列から順序を保ったまま一部の要素を取り出してできる列のことです。また、数列 B が「等差数列」であるとは、隣接する要素の差 B[i+1] - B[i] がすべて同じ値になること(0 <= i < B.length - 1)を指します。例として、

Total 5990 -コンピューター  FirstPage PreviousPage NextPage LastPage CurrentPage:154/300  20-コンピューター/Page Goto:1 148 149 150 151 152 153 154 155 156 157 158 159 160