トップページに戻る
次のC++のサンプルへ
前のC++のサンプルへ
Problem35 100万未満の巡回素数は何個か?
問題
197は巡回素数と呼ばれる. 桁を回転させたときに得られる数 197, 971, 719 が全て素数だからである.
100未満には巡回素数が13個ある: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, および97である.
100万未満の巡回素数は何個か?
ソース
#include <vector>
#include <valarray>
#include <algorithm>
#include <Windows.h>
#include <string>
std::vector<int> SosuuVect;
//エラトステネスの篩
void Eratosthenes()
{
std::valarray<bool> IsSosuuArr(true,1000000);
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();
//const int SikiiVal = 100;
const int SikiiVal = 1000000;
std::vector<int>::iterator wkIt = std::lower_bound(SosuuVect.begin(),SosuuVect.end(),SikiiVal);
SosuuVect.erase(wkIt,SosuuVect.end());
int cnt = 0;
for (int I = 0; I <= (int)SosuuVect.size()-1; I++) {
bool IsOK = true;
char wkCharArr[100]; wsprintf(wkCharArr,"%d",SosuuVect.at(I));
const int wkCharArrUB = (int)strlen(wkCharArr)-1;
for (int J = 0; J <= wkCharArrUB; J++) {
std::string WillCastInt;
for (int K = 0; K <= wkCharArrUB; K++) {
int wkP = J + K;
if (wkP > wkCharArrUB) wkP -= wkCharArrUB + 1;
WillCastInt += wkCharArr[wkP];
}
if(std::binary_search(SosuuVect.begin(),SosuuVect.end(),atoi(WillCastInt.c_str()))==false){
IsOK = false;
break;
}
}
if(IsOK) printf("%dは%d番目の巡回素数\n",SosuuVect.at(I),++cnt);
}
}
実行結果
省略
933199は51番目の巡回素数
939193は52番目の巡回素数
939391は53番目の巡回素数
993319は54番目の巡回素数
999331は55番目の巡回素数
解説
2ではなく2を含んでいたら除外する。
5ではなく5を含んでいたら除外する。
といったフィルタを素数リストに行ってもいいかもしれません。