C++で合計がnとなる連続する整数列の個数を数えるプログラム
問題概要
ある整数 n が与えられたとき、合計がちょうど n になる「正の連続する整数からなるリスト」の個数を求めます。
例えば、入力が n = 15 の場合、出力は 4 になります。条件を満たすリストは次の4つです。
- [1, 2, 3, 4, 5]
- [4, 5, 6]
- [7, 8]
- [15]
解法のアプローチ(スライディングウィンドウ)
この問題はスライディングウィンドウ(尺取り法)を使うことで効率的に解けます。区間 [begin, end] 内の合計を管理しながら、ウィンドウを伸縮させていくのがポイントです。
具体的な手順は以下の通りです。
begin := 1、end := 1、x := (n + 1) / 2で初期化します。sum := 0とします。end <= xの間、以下を繰り返します。sum := sum + endとしてウィンドウを右に広げます。sum >= nの間、以下を繰り返します。sum == nであれば、カウントを1増やします。sum := sum - beginとして先頭を取り除き、beginを1増やします。
endを1増やします。
- 最後に
count + 1を返します。これは単一要素のリスト [n] 自身を答えに含めるためです。
なお、探索範囲を (n + 1) / 2 までに絞れるのは、2つ以上の連続する正の整数の和が n になるとき、その最大値は高々 (n+1)/2 であるためです。これにより無駄な探索を省けます。
C++での実装例
#include <iostream>
using namespace std;
int solve(int n) {
int begin = 1, end = 1, x = (n + 1) / 2, count = 0;
long int sum = 0;
while (end <= x) {
sum += end;
while (sum >= n) {
if (sum == n)
count++;
sum -= begin;
begin++;
}
end++;
}
return count + 1;
}
main() {
cout << (solve(15));
}
入力
15
出力
4
計算量
このアルゴリズムの時間計算量は O(n)、空間計算量は O(1) です。各要素の追加・削除がそれぞれ高々1回ずつ行われるため、全体でも線形時間で処理が完了します。
-
C++でXとの合計がフィボナッチ数になるノードを数える方法
各ノードに数値の重みが割り当てられた二分木が与えられます。この記事の目的は、「ノードの重み + X」の計算結果がフィボナッチ数となるノードの個数を求めることです。フィボナッチ数列とは、0, 1, 1, 2, 3, 5, 8, 13… のように続く数列で、n番目の数は(n−1)番目と(n−2)番目の数の和になります。たとえば重みが13であればフィボナッチ数に該当するため、そのノードはカウント対象となります。入力例1temp = 1 の場合。値を入力すると、以下のような木が構成されます。出力Count the nodes whose sum with X is a Fibonacci number
-
Pythonで二分木の合計がkとなるパスの数を数える方法
問題の概要 二分木と値 k が与えられたとき、あるノードからその子孫へ向かうパスのうち、通過するノードの値の合計がちょうど k と一致するものがいくつ存在するかを求める問題です。 例えば、次のような二分木を考えてみましょう。 このとき k = 5 であれば、出力は 2 となります。条件を満たすパスは [2, 3] と [1, 4] の2つだからです。 解き方のアプローチ:累積和(prefix sum)の活用 この問題は「累積和(prefix sum)」というテクニックを使うことで、全ノードを一度だけ訪問する効率的なアルゴリズムとして解けます。考え方の手順は以下の通りです。 count:マッ