トップページに戻る    次のC#のサンプルへ    前のC#のサンプルへ

Problem50 100万未満の素数を連続する素数の和で表す

問題

素数41は6つの連続する素数の和として表せる:

41 = 2 + 3 + 5 + 7 + 11 + 13.
100未満の素数を連続する素数の和で表したときにこれが最長になる.

同様に, 連続する素数の和で1000未満の素数を表したときに最長になるのは953で21項を持つ.

100万未満の素数を連続する素数の和で表したときに最長になるのはどの素数か?


ソース

using System;
using System.Linq;

class Program
{
    //const int MaxVal = 100 - 1;
    //const int MaxVal = 1000 - 1;
    const int MaxVal = 1000000 - 1;

    static int[] SosuuArr = new int[MaxVal];

    //エラトステネスの篩
    static void Eratosthenes()
    {
        for (int I = 2; I <= SosuuArr.GetUpperBound(0); I++) {
            SosuuArr[I] = I;
        }
        for (int I = 2; I * I <= SosuuArr.GetUpperBound(0); I++) {
            if (I != 2 && I % 2 == 0) continue;

            if (SosuuArr[I] != 0) {
                for (int J = I * 2; J <= SosuuArr.GetUpperBound(0); J += I) {
                    SosuuArr[J] = 0;
                }
            }
        }
    }

    static void Main()
    {
        Eratosthenes();
        SosuuArr = SosuuArr.Where(X => X != 0).ToArray();

        int SaveSumVal = 0;
        int MaxKousuu = 0;

        for (int I = 0; I <= SosuuArr.GetUpperBound(0); I++) {
            if (SosuuArr.GetUpperBound(0) - I + 1 < MaxKousuu) break;
            if (SosuuArr[I] * 2 > MaxVal) break;

            int SumVal = 0;
            int KariMaxKousuu = 0;

            for (int J = I; J <= SosuuArr.GetUpperBound(0) - 1; J++) {
                SumVal += SosuuArr[J];
                if (SumVal > SosuuArr[SosuuArr.GetUpperBound(0)]) break;
                KariMaxKousuu++;

                if (Array.BinarySearch<int>(SosuuArr, SumVal) >= 0) {
                    if (MaxKousuu < KariMaxKousuu) {
                        SaveSumVal = SumVal;
                        MaxKousuu = KariMaxKousuu;
                    }
                }
            }
        }
        Console.WriteLine("{0}で最大項数={1}", SaveSumVal, MaxKousuu);
    }
}


実行結果

997651で最大項数=543


解説

if文とbreak文による、3つの打ち切り条件を仕掛けてあります。