トップページに戻る
次のC++のサンプルへ
前のC++のサンプルへ
Problem47 連続する4つの数がそれぞれ4つの異なる素因数
問題
連続する2つの数がそれぞれ2つの異なる素因数を持つのは
14 = 2*7
15 = 3*5 の場合である
同様に連続する3つの数がそれぞれ3つの異なる素因数を持つのは
644 = 2の2乗*7*23
645 = 3*5*43
646 = 2*17*19 の場合である
連続する4つの数がそれぞれ4つの異なる素因数を持つ場合を考え、連続する数の中で最小のものを答えよ
ソース
#include <valarray>
#include <vector>
#include <map>
#include <algorithm>
#include <string>
#include <Windows.h>
//const int NeedPair = 2;
//const int NeedPair = 3;
const int NeedPair = 4;
const int Jyougen = 135000;
std::vector<int> SosuuVect;
std::vector<int> DeriveSoinsuuVect(int pTarget);
//エラトステネスの篩
void Eratosthenes()
{
std::valarray<bool> IsSosuuArr(true,Jyougen+1);
for (int I = 2; I * I <= (int)IsSosuuArr.size()-1; I++) {
if(IsSosuuArr[I] == false) continue;
for (int J = I * 2; J <= (int)IsSosuuArr.size()-1; J += I) {
IsSosuuArr[J] = false;
}
}
for (int I = 2; I <= (int)IsSosuuArr.size()-1; I++) {
if(IsSosuuArr[I] == false) continue;
SosuuVect.push_back(I);
}
}
void main()
{
Eratosthenes();
std::map<int,std::vector<int> > SoinsuuBunkaiMap;
for (int I = 2; I <= Jyougen; I++) {
std::vector<int> SoinsuuVect = DeriveSoinsuuVect(I);
char wkCharArr[100];wsprintf(wkCharArr,"%dの素因数は",I);
std::string WillOut = wkCharArr;
for(std::vector<int>::iterator it = SoinsuuVect.begin();it!=SoinsuuVect.end();it++){
wsprintf(wkCharArr,"%d,",*it);
WillOut += wkCharArr;
}
printf("%s\n",WillOut.c_str());
SoinsuuBunkaiMap.insert(std::pair<int,std::vector<int> > (I,SoinsuuVect));
if (SoinsuuBunkaiMap[I].size() == NeedPair
&& SoinsuuBunkaiMap.size() >= NeedPair) {
bool IsOK = true;
for (int J=I-NeedPair+1 ; J<=I-1 ; J++) {
if (SoinsuuBunkaiMap[J].size() != NeedPair) {
IsOK = false;
break;
}
}
if (IsOK) {
printf("Answer=%d\n",I-NeedPair+1);
return;
}
}
if (I % 10000 == 0) { //Mapから不要になったキーをerase
std::map<int,std::vector<int> >::iterator endIt = SoinsuuBunkaiMap.end();
std::advance(endIt, -NeedPair);
SoinsuuBunkaiMap.erase(SoinsuuBunkaiMap.begin(),endIt);
}
}
}
std::vector<int> DeriveSoinsuuVect(int pTarget)
{
std::vector<int> SoinsuuVect;
if(std::binary_search(SosuuVect.begin(),SosuuVect.end(),pTarget)){
SoinsuuVect.push_back(pTarget);
return SoinsuuVect;
}
for(std::vector<int>::iterator it=SosuuVect.begin();it!=SosuuVect.end();it++){
bool FirstFlag = true;
while (pTarget % (*it) == 0) {
if (FirstFlag) {
FirstFlag = false;
SoinsuuVect.push_back(*it);
}
pTarget /= (*it);
}
if (pTarget == 1) break;
}
return SoinsuuVect;
}
実行結果
省略
134041の素因数は311,431,
134042の素因数は2,67021,
134043の素因数は3,7,13,491,
134044の素因数は2,23,31,47,
134045の素因数は5,17,19,83,
134046の素因数は2,3,11,677,
Answer=134043
解説
Mapコンテナで素因数分解の結果をキャッシュしつつ、
eraseメソッドで不要になったキーをeraseしてます。
MSDN --- map::erase