C++

 Computer >> コンピューター >  >> プログラミング >> C++
  1. C++で絶対差が1以下となる要素の最大数を求める方法

    n個の要素からなる配列が与えられたとします。この配列から、選んだ任意の2つの要素の絶対差が1以下になるように、最大でいくつの要素を選べるかを求める問題です。例えば、配列が [2, 2, 3, 4, 5] の場合、答えは3となり、要素数が最大となる組み合わせは「2, 2, 3」です。解法の考え方絶対差が0または1であるということは、選べる数値は「x」と「x + 1」の2種類に限られることを意味します。そこで、各要素の出現回数(頻度)を記録しておき、隣り合う2つの値の頻度の合計が最大になるところを探せば、それが求める答えとなります。アルゴリズムの手順mapを使って、配列内の各要素の出現回数をカウン

  2. C++プログラミングで独自の代入演算子を定義すべきケースとは?

    本記事では、C++において独自の代入演算子(コピー代入演算子)を定義する必要がある状況について解説します。クラスがポインタメンバを持たない場合、通常は代入演算子やコピーコンストラクタを自作する必要はありません。C++コンパイラは、すべてのクラスに対してデフォルトのコピーコンストラクタと代入演算子を自動的に生成します。しかし、これらのデフォルトの動作が不十分なケースでは、独自の代入演算子を実装しなければなりません。問題となるコード例#include<iostream> using namespace std; class MyClass { // ユーザー定義の代入演算子・コピーコン

  3. C++である整数の各桁を並べ替えて作れる最大の数を求めるアルゴリズム

    問題概要n桁の整数が与えられたとき、その数を構成するすべての桁の数字を使って作成できる最大の数を求めることを考えます。例えば、与えられた数が 339625 の場合、各桁を並べ替えることで作れる最大の数は 965332 となります。解決のアプローチこの問題は、各桁の数字を降順(非増加順)にソートして出力するだけで簡単に解くことができます。しかし、ここではさらに効率的な方法を紹介します。具体的には、サイズ10の配列を用意して各数字(0〜9)の出現頻度を記録します。その後、9から0へと順番に走査しながら、出現回数に応じて数字を配置していくことで、最大の数を効率よく構築できます。この手法の時間計算量は

  4. C++が完全なオブジェクト指向言語ではない理由とは?部分的なオブジェクト指向の理由を解説

    はじめにオブジェクト指向プログラミング言語の基本的な特徴として、継承(Inheritance)、カプセル化(Encapsulation)、ポリモーフィズム(Polymorphism)の3つが挙げられます。これらの機能を完全にサポートする言語が「オブジェクト指向プログラミング言語」と呼ばれます。C++はこれらの3つの機能を備えていますが、完全にはサポートしていません。そのため、C++は「部分的なオブジェクト指向言語」と分類されることがあります。ここでは、C++が完全なオブジェクト指向言語とみなされない理由を詳しく見ていきましょう。理由1:main()関数がクラスの外に存在するC++ではプログラム

  5. C++で階乗を割り切る数の最大の累乗を求める方法

    2つの整数 n と fact が与えられたとき、「fact!(fact の階乗)を割り切る n の最大の累乗」を求める問題を考えてみましょう。例えば、fact = 5、n = 2 の場合、答えは 3 になります。これは 5! = 120 であり、120 は 23 = 8 で割り切れるためです。 ルジャンドルの定理(Legendres Formula)とは この問題を効率的に解くには、ルジャンドルの定理を利用します。この定理は「素数 p が fact! を割り切る最大の累乗」を求めるための公式で、次のように表されます。 まず n のすべての素因数を求め、それぞれの素因数について fact!

  6. gcd(P[i], i) > 1 となるインデックスの個数がちょうど K になる順列を C++ で求める方法

    問題の概要2つの整数 N と K が与えられたとします。このとき、範囲 [1, N] の整数からなる順列 P のうち、gcd(P[i], i) > 1 を満たすインデックス(1始まり)の個数がちょうど K 個になるものを見つける必要があります。例えば、N = 4、K = 3 の場合、出力は [1, 2, 3, 4] となります。なぜなら、gcd(1, 1) = 1、gcd(2, 2) = 2、gcd(3, 3) = 3、gcd(4, 4) = 4 であり、gcd(P[i], i) > 1 となるのはインデックス 2、3、4 の 3 箇所だからです。解法の考え方この問題には、次のよう

  7. C++で n! mod (k^x) = 0 となる最大の x を求める方法

    2つの整数 n と k が与えられたとき、n! mod (k^x) = 0 を満たす最大の x の値を求める問題を考えます。例えば n = 5、k = 2 の場合、答えは 3 になります。これは n! = 120 であり、x の各値に対する剰余を計算すると次のようになるためです。120 mod 2^0 = 0、120 mod 2^1 = 0、120 mod 2^2 = 0、120 mod 2^3 = 0、120 mod 2^4 = 8、120 mod 2^5 = 24、120 mod 2^6 = 56、120 mod 2^7 = 120剰余が 0 となる最大の x は 3 であるため、出力は

  8. C++で時針と分針のなす角がθとなる時刻を求める方法

    問題の概要角度θ(シータ)が与えられたとき、時計の時針と分針がちょうどその角度をなす時刻を「hh:mm」形式で求めることを考えます。例えば、角度が90°であれば、答えの一つとして「3:00」が挙げられます。解き方のアプローチ時計は12時間表示のため、時は12通り(0〜11)、分は60通り(0〜59)の組み合わせが存在します。つまり、調べるべき時刻は最大でも12×60=720通りです。そこで、すべての時刻の組み合わせを順番に調べ、各時刻における時針と分針のなす角を計算します。その角度が与えられたθと一致した時点で、その時刻を出力します。角度の計算方法時針と分針の角度は、それぞれ次の式で求められま

  9. C++で二分木の最大垂直和を求める方法

    はじめに二分木が与えられたとき、垂直順序走査における各垂直列のノード値の合計を計算し、その中から最大値を求めて出力するのが本記事の課題です。例として、以下のような二分木を考えてみましょう。この二分木を垂直順序走査すると、各列の合計は次のようになります。4 2 1 + 5 + 6 = 12 3 + 8 = 11 7 9各列の合計の中で最大となるのは 12 です。アルゴリズムの考え方アプローチはシンプルです。幅優先探索(BFS)を用いて垂直順序走査を行い、各ノードに水平距離を割り当てます。ルートの水平距離を 0 とし、左に移動するごとに -1、右に移動するごとに +1 とします。同じ水平距離を持つ

  10. C++でセットビットがn個(1≤n≤k)のkビット数の全組み合わせをソート順に生成する方法

    数値 k が与えられたとき、セットビット(値が1になっているビット)が n 個(1 ≤ n ≤ k)である k ビット数のすべての組み合わせを求める問題です。出力は、セットビットが1個の数から始まり、2個、3個と順に続き、最後にすべてのビットが1になった数まで表示します。また、セットビットの数が同じ数同士については、値が小さい方を先に出力します。例えば k = 3 の場合、出力される数の並びは [001, 010, 100, 011, 101, 110, 111] となります。アプローチ:動的計画法ここでは動的計画法(DP)を用いて、セットビットが n 個(1 ≤ n ≤ k)である k ビッ

  11. C++で座標の集合から作れる長方形の最小面積を求める方法

    問題の概要 XY平面上にいくつかの点が与えられたとします。これらの点から作ることができる長方形のうち、面積が最小になるものを求めます。ただし、長方形の各辺はX軸およびY軸と平行でなければならず、長方形が構成できない場合は0を返します。 例えば、点の集合が [(1, 1), (1, 3), (3, 1), (3, 3), (2, 2)] の場合、(1, 1)、(1, 3)、(3, 1)、(3, 3) の4点を使って長方形を作れるため、答えは4となります。 解法の考え方 この問題を効率よく解くには、まず点をx座標ごとに整理し、同じ縦の直線上にある点同士をグループ化します。続いて、各グループ内の点の

  12. C++で全ての本を購入するための最小コストを求める方法

    問題の概要n個の要素からなる配列があるとします。各要素は本の評価(レーティング)を表しています。以下の条件を満たすように、すべての本を購入する際の最小コストを求めます。各本のコストは最低でも1ドル以上でなければならないある本の評価が隣接する本(左または右)の評価より高い場合、その本のコストは隣の本よりも高く設定しなければならない例えば、評価の配列が [1, 3, 4, 3, 7, 1] の場合、出力は 10 になります。これは 1 + 2 + 3 + 1 + 2 + 1 = 10 となるためです。解法の考え方この問題を効率的に解くには、LtoR と RtoL という2つの補助配列を用意し、すべ

  13. C++で「自分より大きい要素が2つ以上ある」配列内のすべての要素を検索する方法

    問題の概要n個の数値で構成される配列が与えられたとき、「自分自身より大きい要素が少なくとも2つ存在する」すべての要素を見つけることを考えます。例えば、配列が A = [2, 8, 7, 1, 5] の場合、結果は [2, 1, 5] となります。これらの要素には、それぞれ2つ以上のより大きな要素が配列内に存在するためです。解決のアプローチこの問題は、配列を2回走査するだけで効率的に解くことができます。1回目の走査で、配列の最大値(first_max)と2番目に大きい値(second_max)を求めます。2回目の走査で、second_maxより小さいすべての要素を出力します。この方法の時間計算量

  14. C++で最長共通接頭辞を得るための最小シフト回数を求めるアルゴリズム

    問題概要 同じ長さを持つ2つの文字列AとBが与えられたとします。1回のシフト操作によって、文字列Bを1文字ずつ回転(ローテート)できるものとします。このとき、AとBの間で最長の共通接頭辞(プレフィックス)が得られるようにするために必要な最小のシフト回数を求めるのが本問題です。 たとえば、A = “programminglanguage”、B = “computerprogramming” の場合、Bを8回シフトすれば共通接頭辞 “programming” が得られるため、最小シフト回数は8、接頭辞は “pro

  15. C++で1からNまでの準素数(Almost Prime)の個数を求める方法

    ある数 N が与えられたとき、1からNまでの範囲に含まれる「準素数(almost prime)」の個数を求める問題を考えてみましょう。準素数とは、異なる素因数をちょうど2つ持つ数のことです。素因数以外の約数(合成数の約数)はいくつあっても構いませんが、その中に含まれる素因数は正確に2種類である必要があります。例えば、Nが10の場合、出力は2になります。これは、条件を満たす数が 6(= 2 × 3)と 10(= 2 × 5)の2つしか存在しないためです。アプローチ:エラトステネスの篩を活用するこの問題を効率的に解くには、エラトステネスの篩(Sieve of Eratosthenes)を使って素数

  16. 【C++】3つの連続する要素ごとに1つ選ぶ場合の最小合計を求めるアルゴリズム

    n個の要素からなる配列が与えられたとき、配列内の3つの連続する要素ごとに少なくとも1つの要素を選ぶという条件を満たしながら、選んだ要素の合計を最小化する問題を考えてみましょう。 問題の例 例えば、配列が [1, 2, 3, 6, 7, 1] の場合、出力は 4 になります。これは「3」と「1」を選ぶことで 3 + 1 = 4 が達成できるからです。 このとき、配列には次のような連続する3要素の部分配列が存在します。 [1, 2, 3] [2, 3, 6] [3, 6, 7] [6, 7, 1] これらすべての部分配列から1つずつ要素を選ぶ必要があるため、単純に小さい要素だけを選ぶわけにはい

  17. 要素の範囲が制限されていない配列の重複をC++で検出する方法

    N個の整数からなる配列が与えられたとします。ここでは、その配列に含まれる重複要素を出力する方法を解説します。重複が1つも存在しない場合は、-1を返します。例えば、配列が [12, 15, 12, 3, 6, 12, 3, 48, 56, 8, 48] の場合、重複している要素は [12, 3, 48] となります。この問題は、C++の unordered_map(ハッシュマップ)を使うことで効率的に解決できます。要素の値の範囲が制限されていない場合でも、ハッシュマップを利用すれば各要素の出現回数を簡単に記録できます。アルゴリズムの考え方基本的な手順は以下のとおりです。各要素の出現回数を記録する

  18. C++で配列の積が元より大きくなるように全要素に割り当てる最小値を求める方法

    問題の概要n個の要素からなる配列が与えられたとします。配列のすべての要素をある最小値xに更新し(arr[i] = x)、新しい配列の全要素の積が、元の配列の全要素の積よりも厳密に大きくなるようにします。ここで、1 <= n <= 10^5、1 <= arr[i] <= 10^10 という制約が課せられています。例えば、配列が [4, 2, 1, 10, 6] の場合を考えてみましょう。このとき答えは4になります。実際に、4 × 4 × 4 × 4 × 4 = 1024 となり、元の積 4 × 2 × 1 × 10 × 6 = 480 よりも大きくなることが確認できます。

  19. C++でO(1)の追加メモリを使って配列内の重複要素を効率的に検出する方法

    問題の概要0からn-1までの範囲の数値が格納された配列を考えます。このとき、同じ数値は何度でも繰り返し現れる可能性があります。ここでの課題は、余分なメモリ(補助配列など)を使用せずに、重複している数値をすべて見つけることです。例えば、n = 7 の場合で、配列が [5, 2, 3, 5, 1, 6, 2, 3, 4, 5] のようになっているとします。このとき答えは 5, 2, 3 となります。アルゴリズムの考え方:符号マーキング法この問題をO(1)の追加空間で解く鍵となるのが「符号(正負)をマーキングとして利用する」テクニックです。配列の要素はすべて0からn-1の範囲内であるため、各値は必ず

  20. C++でシャッフルされた配列から欠落している数値を見つける方法

    2つの配列AとBがあるとします。配列Aにはn個の要素が含まれており、配列BにはAのすべての要素が含まれていますが、要素の順序がシャッフルされており、そのうち1つの要素が削除されています。この削除された要素(欠落している数値)を見つける必要があります。例えば、A = [4, 8, 1, 3, 7]、B = [7, 4, 3, 1] の場合、配列Bには「8」が存在しないため、出力は8となります。XOR(排他的論理和)を使った解法この問題は、XORの性質を利用することで効率的に解くことができます。各要素は配列Aと配列Bにそれぞれ1回ずつ、合計2回出現しますが、欠落している要素だけは配列Aにしか存在し

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