トップページに戻る
次のC#のサンプルへ
前のC#のサンプルへ
Problem204 一般化ハミング数
問題
ハミング数とは, どの素因数も5以下であるような正整数のことである.
最初から順に並べると, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15となる.
1億以下のハミング数は1105個ある.
素因数がn以下の正整数を, type nの一般化ハミング数と呼ぶことにする.
するとハミング数はtype 5の一般化ハミング数である.
10億以下のtype 100の一般化ハミング数の個数を答えよ.
ソース
using System;
using System.Collections.Generic;
class Program
{
static int[] mSosuuArr;
//エラトステネスの篩で上限以下の素数の配列を作成
static void Eratosthenes(int pJyougen)
{
var IsSosuuArr = new System.Collections.BitArray(pJyougen + 1);
for (int I = 2; I <= IsSosuuArr.Count - 1; I++) {
IsSosuuArr[I] = true;
}
for (int I = 2; I * I <= IsSosuuArr.Count - 1; I++) {
if (IsSosuuArr[I] == false) continue;
for (int J = I * 2; J <= IsSosuuArr.Count - 1; J += I) {
IsSosuuArr[J] = false;
}
}
var SosuuList = new List<int>();
for (int I = 2; I <= IsSosuuArr.Count - 1; I++) {
if (IsSosuuArr[I]) SosuuList.Add(I);
}
mSosuuArr = SosuuList.ToArray();
}
static void Main()
{
Solve(100000000, 5);
Solve(1000000000, 100);
}
struct JyoutaiDef
{
internal int CurrInd;
internal int ProdVal;
}
static void Solve(int pJyougen, int pType)
{
Eratosthenes(pType);
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.CurrInd = 0;
WillPush.ProdVal = 1;
Stk.Push(WillPush);
int AnswerCnt = 0;
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
//Console.WriteLine("Type{0}のハミング数{1}を発見", pType, Popped.CurrProd);
AnswerCnt++;
for (int I = Popped.CurrInd; I <= mSosuuArr.GetUpperBound(0); I++) {
WillPush.CurrInd = I;
long wkProd = (long)Popped.ProdVal * mSosuuArr[I];
if (wkProd > pJyougen) break;
WillPush.ProdVal = (int)wkProd;
Stk.Push(WillPush);
}
}
Console.WriteLine("{0}以下でType{1}のハミング数は、{2}個", pJyougen, pType, AnswerCnt);
}
}
実行結果
100000000以下でType5のハミング数は、1105個
1000000000以下でType100のハミング数は、2944730個
解説
深さ優先探索で一般化ハミング数を列挙してます。