C++

 Computer >> コンピューター >  >> プログラミング >> C++
  1. C++で指定された条件を満たす最初のN個の自然数の順列を求めるアルゴリズム

    2つの整数 N と K が与えられたとき、最初の N 個の自然数からなる順列 P のうち、すべての 1 ≤ i ≤ N に対して 1 を満たす要素がちょうど K 個になるような順列を求める問題を考えてみましょう。例えば、N = 3、K = 1 の場合、答えは「2, 1, 3」になります。実際に確認すると、gcd(2, 1) = 1、gcd(1, 2) = 1、gcd(3, 3) = 3 となり、条件を満たす要素は1つだけであることがわかります。解法のアプローチこの問題の解法は非常にシンプルです。末尾の K 個の要素は元の位置にそのまま残し、残りの要素を1つずつ後ろにずらします。具体的には、i

  2. C++で3で割り切れるが6で割り切れない数nの順列を求める方法

    問題の概要ある数nが与えられたとき、その桁を並べ替えた順列の中から「3で割り切れるが、6では割り切れない」数を見つけることを考えます。そのような値を作ることができない場合は、-1を返します。例えば、nが336の場合、答えの候補として363が出力されます。解法の考え方ご存知の通り、6で割り切れる数とは、3と2の両方で割り切れる数のことです。つまり、3で割り切れる偶数は必ず6でも割り切れます。そこで、3で割り切れかつ偶数である数の桁を入れ替えて奇数にすることができれば、その数が求める答えとなります。ここで重要なポイントとして、桁を並べ替えても各位の数字の合計は変わらないため、元の数が3で割り切れれ

  3. C++でA[i] mod Kが最大になるような配列内の素数Kを見つける方法

    問題の概要n個の整数からなる配列Aが与えられたとします。この中から要素Kを見つけます。Kは素数であり、考えられるすべてのKの中でA[i] mod Kの値が最大になるものを選びます。条件を満たす数が見つからない場合は、-1を返します。例えば、A = [2, 10, 15, 7, 6, 8, 13] の場合、出力は13になります。この配列には3つの素数(2、7、13)が含まれており、それぞれの剰余の最大値は以下のようになります。K = 2 の場合:15 mod 2 = 1K = 7 の場合:6 mod 7 = 6K = 13 の場合:10 mod 13 = 10この中で最も大きいのは10なので、答

  4. C++で1からnまでの素数の積を求める方法

    数値 n が与えられたとき、1 から n までの範囲に含まれる素数をすべて掛け合わせた積を求めることを考えます。例えば n = 7 の場合、素数は 2・3・5・7 なので、出力は 2 × 3 × 5 × 7 = 210 となります。アプローチ:エラトステネスの篩この問題を効率的に解くには、エラトステネスの篩(ふるい)と呼ばれる古典的なアルゴリズムを使います。この手法では、2 から始めて各素数の倍数を順に除外していくことで、1 から n までのすべての素数を高速に見つけることができます。その後、見つかった素数をすべて掛け合わせれば答えが得られます。アルゴリズムの手順サイズ n+1 の真偽値配列を

  5. C++で文字列内の最初の繰り返し文字を検索する方法

    はじめに文字列が与えられたとき、その中で最初に繰り返し出現する文字を見つける問題を考えてみましょう。例えば、文字列が「Hello Friends」の場合、最初の繰り返し文字は「l」となります。「l」が2つ連続して出現しているためです。解決アプローチ:ハッシュテーブルの活用この問題を効率的に解くには、ハッシュ技法を利用します。手順は以下の通りです。空のハッシュテーブルを作成します。文字列の各文字を先頭から順番に1文字ずつ走査します。現在の文字がハッシュテーブルに存在しない場合は、その文字を挿入します。すでに存在する場合は、その文字を答えとして返します。この手法を使えば、時間計算量O(n)(nは文

  6. C++のマトリックスで安全なセル(植物)を見つける方法

    問題概要 文字から構成される2次元マトリックス mat[][] が与えられたとします。各セルには次の3種類の文字が格納されています。 Z:ゾンビ P:植物 *:更地(何もない土地) ゾンビは、自分の隣接セル(上下左右だけでなく斜め方向を含む8方向)にいる植物を攻撃することができます。このとき、ゾンビの攻撃を受けることなく安全に生存できる植物の数を求めるのが本記事の目的です。 例として、次のようなマトリックスを考えてみましょう。 この場合、ゾンビから安全な植物はわずか2つだけです。 アルゴリズムの考え方 アプローチは非常にシンプルで、以下の手順で実現できます。 マトリックスの全要素を1つ

  7. C++で販売価格と利益率・損失率から原価を求める方法

    販売価格が分かっており、そこに利益率または損失率の情報が与えられている場合を考えてみましょう。このとき、商品の原価(仕入れ値)を逆算して求める必要があります。その計算式は以下の通りです。 $$原価=\frac{販売価格×100}{100+利益率}$$ $$原価=\frac{販売価格×100}{100-損失率}$$ 利益が出ている場合は分母に利益率を加算し、損失が出ている場合は分母から損失率を減算することで、元々の仕入れ値を算出できます。この式をC++の関数として実装すると、次のようになります。 サンプルコード #include<iostream> using namespace

  8. C++で K mod P = 0 かつ Q mod K = 0 を満たす最小の数 K を求める方法

    問題の概要2つの整数 P と Q が与えられたとき、次の条件を同時に満たす最小の整数 K を求める問題を考えてみましょう。K mod P = 0 かつ Q mod K = 0そのような K が存在しない場合は -1 を出力します。例えば、P = 2、Q = 8 の場合、答えは K = 2 となります。なぜなら、2 mod 2 = 0 であり、8 mod 2 = 0 というように、両方の条件を満たすからです。解法の考え方この問題の鍵となるのは、条件を整理することです。K mod P = 0 より、K は P の倍数であるQ mod K = 0 より、K は Q の約数であるP の倍数の中で最小の

  9. C++で配列内の各要素より大きい直近の値を効率的に検索する方法

    この記事では、配列内のすべての要素について、それより大きい値の中で最も近いもの(次に大きい要素)を検索する方法を解説します。要素 x より大きい値が配列内に存在する場合はその値を出力し、存在しない場合は -1 を返します。例として、配列が [10, 5, 11, 6, 20, 12] の場合を考えてみましょう。このとき、各要素に対する次に大きい値は [11, 6, 12, 10, -1, 20] となります。最大値である 20 より大きい要素は配列内に存在しないため、-1 を出力します。解決のアプローチこの問題を解くには、C++ STL の set(セット)を利用します。set は二分探索木(

  10. C++でnに最も近いmの倍数を求めるアルゴリズムと実装方法

    問題の概要2つの整数 n と m が与えられたとき、「n に最も近く、かつ m で割り切れる数」を見つけることを考えます。候補が複数存在する場合は、絶対値が最大となる数を返します。また、n が m で完全に割り切れる場合は、そのまま n を返します。例えば、n = 13、m = 4 の場合、出力は 12 になります。13 に近い 4 の倍数としては 12 と 16 が候補ですが、13 との距離が近いのは 12 であるため、これが答えとなります。解決の手順この問題は、次のステップに従って解くことができます。まず q := n / m とし、n1 := m * q を計算しますn * m >

  11. C++で3つのリンクリストに共通する要素を効率的に検索する方法(ハッシュ活用)

    3つのリンクリストが与えられたとき、それらすべてに共通して存在する要素を見つける問題を考えてみましょう。例えば、リストが [10, 12, 15, 20, 25]、[10, 12, 13, 15]、[10, 12, 15, 24, 25, 26] の3つである場合、共通する要素は 10、12、15 となります。この問題はハッシュテーブル(ハッシュマップ)を使うことで効率的に解決できます。各要素の出現状況を「頻度カウント」として管理し、3つのリストすべてに出現した要素を特定する仕組みです。アルゴリズムの手順ステップ1: 空のハッシュテーブルを作成します。最初のリンクリストを走査し、各要素をハッシ

  12. C++で長さNのバイナリ文字列のうち3つ以上の連続した1を含むものの個数を求める方法

    問題の概要整数Nが与えられたとき、長さNのすべての異なるバイナリ文字列のうち、少なくとも3つの連続した1を含むものの総数を求めます。例えば、N = 4の場合、条件を満たす文字列は「0111」「1110」「1111」の3つであるため、出力は3となります。アプローチ:動的計画法(DP)この問題は動的計画法を用いることで効率的に解くことができます。ここで、DP(i, x)を「長さiの文字列のうち、位置i+1からi+xまでにx個の連続した1が並んでいる文字列の数」と定義します。すると、漸化式は次のように表されます。DP(i, x) = DP(i – 1, 0) + DP(i – 1, x + 1)この

  13. C++で3つのソート済み配列から共通要素を効率的に見つける方法

    はじめに3つの配列が与えられ、そのすべてに共通して存在する要素を見つけたいとします。例えば、配列が [10, 12, 15, 20, 25]、[10, 12, 13, 15]、[10, 12, 15, 24, 25, 26] の場合、3つの配列すべてに共通する要素は 10、12、15 となります。配列がソート済みであることを利用すると、3つのポインタを使って各配列を一度だけ走査するだけで済む、非常に効率的なアルゴリズムが実現できます。時間計算量は O(n1 + n2 + n3) です。アルゴリズムの考え方配列 A1、A2、A3 を走査中の現在の要素をそれぞれ x、y、z とします。このとき、以

  14. C++で1からnまでの「0」と「1」のみを含む整数の個数を求める方法

    問題の概要ある数値 n が与えられたとき、1からnまでの整数の中に、「0」と「1」のみで構成される数がいくつあるかを求めることを考えます。例えば、n = 15 の場合、条件を満たすのは「1」「10」「11」の3つであるため、答えは3となります。解法のアプローチこの問題は、再帰関数を使って「0」と「1」だけで作れる整数を順番に生成していくことで、効率的に解くことができます。現在の値 p に対して、末尾に「0」を追加した値(p × 10)と、末尾に「1」を追加した値(p × 10 + 1)の2方向へ再帰的に探索を進め、p が n を超えた時点で探索を打ち切るのがポイントです。C++での実装例#in

  15. C++で数値の2進表現に含まれる長さn以上の連続する「1」を検索する方法

    問題の概要 2つの整数 x と n が与えられたとき、32ビットの2進表現の中から「長さが n 以上となる最初の連続した1の並び」を探し、その開始位置を返すことを考えます。該当する並びが存在しない場合は -1 を返します。 例えば、x = 35、n = 2 の場合、結果は 31 になります。32ビット整数としての 35 の2進表現は以下のとおりです。 00000000000000000000000000100011 この中で2つの「1」が連続して現れているのはインデックス31の位置なので、答えは 31 となります。 解決のアプローチ この問題を解くポイントは、「先頭の0(リーディングゼロ)の個

  16. C++で、xとx+1が同じ個数の約数を持つ範囲(1, N)内の整数xの個数を求める方法

    整数 N が与えられたとき、1 < x < N を満たす整数 x のうち、x と x+1 が同じ個数の正の約数を持つものがいくつあるかを求めます。例えば N = 3 の場合、出力は 1 になります。これは、2 の約数が 1 と 2 の 2 個、3 の約数が 1 と 3 の 2 個であり、両者とも約数の個数が等しいためです。解法のアプローチこの問題は、以下の手順で効率的に解くことができます。N 未満のすべての整数について、約数の個数を事前に計算して配列に格納します。隣り合う数(x と x+1)の約数の個数を比較し、等しくなる箇所を数えます。累積和(prefix sum)を取っておくこ

  17. C++で2つの双方向リンクリストに共通するノード数を求める方法

    問題の概要2つの双方向リンクリスト(二重リンクリスト)が与えられたとき、両方のリストに共通して含まれるノードの総数を求めます。例えば、1つ目のリストが [15, 16, 10, 9, 7, 17]、2つ目のリストが [15, 16, 40, 6, 9] である場合、「15」「16」「9」の3つのノードが共通しているため、答えは3となります。アルゴリズムこの問題は、ネストした2重ループを使って両方のリストを先頭から末尾まで走査することで解決できます。具体的な手順は以下の通りです。外側のループで、1つ目のリストの各ノードを順番に取り出します。内側のループで、そのノードの値が2つ目のリスト内のいずれ

  18. C++で数直線上の点Xに到達するための最小ジャンプ回数を求める方法

    問題の概要整数 X が与えられたとき、0 から出発して X に到達するために必要な最小のジャンプ回数を求めます。最初のジャンプの長さは 1 単位で、それ以降の各ジャンプは直前のジャンプよりちょうど 1 単位ずつ長くなります。また、各ジャンプでは左方向・右方向のどちらにも移動することが許されています。例えば X = 8 の場合、答えは 4 となります。0 → -1 → 1 → 4 → 8 という経路で到達できるからです。解法の考え方この問題を注意深く観察すると、次の性質が成り立つことが分かります。常に右方向にジャンプし続けた場合、n 回のジャンプ後の位置は p = 1 + 2 + 3 + … +

  19. C++で二分木の2つのノード間の距離を求める方法

    問題の概要いくつかのノードを持つ二分木が与えられているとします。このとき、2つのノード u と v の間の「距離」、つまり一方のノードからもう一方のノードへ移動する際に通る辺(エッジ)の本数を求めることを考えます。例として、次のような二分木を扱います。 1 / \ 2 3 / \ / \ 4 5 6 7 \ 8この木において、ノード (4, 6) 間の距離は 4(経路:4 → 2 → 1 → 3 → 6)、ノード (5, 8) 間の

  20. C++で数をa=c・b=dとなる4つの部分に分割する方法の総数を求める

    問題の概要整数 n が与えられたとき、この数を4つの部分(a、b、c、d)に分割する方法のうち、a = c かつ b = d を満たす組み合わせが何通りあるかを求めます。例として n = 20 の場合を考えてみましょう。答えは4通りになり、具体的には以下の組み合わせが該当します。[1, 1, 9, 9][2, 2, 8, 8][3, 3, 7, 7][4, 4, 6, 6]解法のアプローチc = a、d = b であるため、この問題は実質的に「a + b = n / 2 となる正整数のペア (a, b) の個数」を求める問題に帰着できます。これにより、次のようなシンプルなルールが導かれます。n

Total 5990 -コンピューター  FirstPage PreviousPage NextPage LastPage CurrentPage:103/300  20-コンピューター/Page Goto:1 97 98 99 100 101 102 103 104 105 106 107 108 109