C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++で整数を連続する自然数の和として表現する方法の数を求める

整数 num が入力として与えられたとき、その数を「2つ以上の連続する自然数の和」として表現できるパターンが何通りあるかを求めるのが本記事の目的です。たとえば n=3 の場合は 1+2 と表現できるため、答えは 1 通りになります。

入力例

num=6

出力

連続する数の和として数を表現する方法の数:1

説明

6 を連続する自然数の和で表現する方法:1+2+3

入力例

num=19

出力

連続する数の和として数を表現する方法の数:1

説明

19 を連続する自然数の和で表現する方法:9+10

アルゴリズムの考え方

ここで採用するアプローチは、対象の数を「a + (a+1) + (a+2) + … + (a+i)」という連続する自然数の和の形で表現するものです。この和は次のように変形できます。

a×(i+1) + (1+2+…+i) = a×(i+1) + i×(i+1)/2

したがって、次の等式が成り立ちます。

num = a×(i+1) + i×(i+1)/2

これを開始値 a について解くと、

a = [num − i×(i+1)/2] / (i+1)

あとは i を 1 から順に増やしながら「i×(i+1)/2 < num」を満たす範囲で a を計算し、a がきれいな整数になれば、その項数での表現が可能であることが分かります。

処理の手順

  • 整数 num を入力として受け取ります。
  • 関数 sum_consecutive(int num) は、num を連続する自然数の和として表現する方法の数を返します。
  • カウンタ変数 count を 0 で初期化します。
  • 計算結果を保持する一時変数 res を float 型で用意します。
  • for ループで i を 1 から始め、「i×(i+1)/2 < num」を満たす間だけ繰り返します。
  • [num − i×(i+1)/2] / (i+1) を計算して res に格納します。
  • res が整数かどうか(res − (int)res が 0 になるか)を判定し、整数であれば count をインクリメントします。
  • ループ終了後の count が、求めるべき表現方法の総数となります。
  • count を結果として返します。

コード例

#include <bits/stdc++.h>
using namespace std;
int sum_consecutive(int num){
    int count = 0;
    int temp = num * 2;
    float res;
    for (int i = 1; i * (i + 1) < temp; i++){
        int store = i + 1;
        res = (1.0 * num - (i * (i + 1)) / 2) / store;
        float check = res - (int)res;
        if(check == 0.0){
            count++;
        }
    }
    return count;
}
int main(){
    int num = 20;
    cout<<"Count of ways to express a number as sum of consecutive numbers are: "<<sum_consecutive(num) << endl;
    return 0;
}

出力

上記のコードを実行すると、次のような出力が得られます。

Count of ways to express a number as sum of consecutive numbers are: 1

補足

サンプルコードの num=20 の場合、20 = 2+3+4+5+6 と表現できるため、答えは 1 通りです。ちなみに数学的には「2つ以上の連続する自然数の和で表せない数」は 2 の累乗(1, 2, 4, 8, 16, …)のみであることが知られています。興味があれば、さまざまな値を入力して挙動を確かめてみてください。

  1. C++で集合をk個の部分集合に分割する方法の総数を動的計画法で求める

    2つの数 e(要素数) と p(分割数) が与えられたとき、「集合の e 個の要素を p 個の部分集合(パーティション)に分割する方法が全部で何通りあるか」を求めるのがこの問題の目的です。 例1 入力 e=4 p=2 出力 Count of number of ways to partition a set into k subsets are: 7 説明 要素が a・b・c・d の4つである場合、これらを2つのグループに分ける方法は次の7通りあります。 (a)−(b,c,d)、(b)−(a,c,d)、(c)−(a,b,d)、(d)−(a,b,c)、(a,b)−(c,d)、(a,c)−(b,

  2. C++で数値が2つの三角数の和として表現できるか判定する方法

    本記事では、ある整数が2つの三角数の和として表現できるかどうかを判定する方法を、C++のコード例とともに分かりやすく解説します。三角数とは三角数とは、1、3、6、10、15…のように、1から順に自然数を加算して得られる数列のことです。点を正三角形の形に並べたときの個数に対応することから「三角数」と呼ばれています。n番目の三角数は次の式で求められます。n × (n + 1) / 2例えば、1、3、6、10などが三角数に該当します。これらを利用すると、16は「6 + 10」という2つの三角数の和として表現できます。判定アルゴリズム判定の手順は非常にシンプルです。N未満のすべての三角数を生成し、セッ