最初はそこそこ高速な計算だったのだが。
f(9999)の場合だけ64ビット整数型を越えてしまう問題に直面。
仕方なく遅い方法で実装し9999だけ特別に書きだしてPrologで計算。
計算時間10分もかかる。
最初に割っておくにはどうすればよいのだろうか
#include<stdio.h>
#include<map>
#include<queue>
#include<iostream>
#include<list>
struct E{
__int64 mod,top,len;
bool operator<(const E& e)const{
if(len!=e.len)return len>e.len;
if(top!=e.top)return top>e.top;
return mod>e.mod;
}
};
struct E2{
std::list<int> li;
bool operator<(const E2& e)const{
return li<e.li;
}
void push_front(int n){
li.push_front(n);
}
void print(){
std::list<int>::iterator it;
for(it=li.begin();it!=li.end();it++){
printf("%d",(*it));
}
printf("\n");
}
};
__int64 to_num(std::list<int> li){
__int64 a=0;
std::list<int>::iterator it;
for(it=li.begin();it!=li.end();it++){
a=a*10+(*it);
}
return a;
}
E2 calc(__int64 n){
std::map<E,E2> memo;
std::priority_queue<E> qu;
__int64 a=1;
E e1;
e1.mod=0;
e1.top=0;
e1.len=0;
qu.push(e1);
E2 e22;
memo[e1]=e22;
int oldLen=0;
while(qu.empty()==false){
e1=qu.top();
if(e1.len>oldLen){
oldLen=e1.len;
a=(a*10)%n;
}
qu.pop();
if(e1.mod==0){
if(e1.top==1||e1.top==2){
return memo[e1];
}
}
for(int i=0;i<=2;i++){
E e2;
e2.len=e1.len+1;
e2.top=i;
e2.mod=(e1.mod+a*i)%n;
if(memo.find(e2)==memo.end()){
E2 e22=memo[e1];
e22.push_front(i);
memo[e2]=e22;
qu.push(e2);
}else{
E2 e22=memo[e1];
e22.push_front(i);
if(e22<memo[e2])memo[e2]=e22;
}
}
}
return e22;
}
int main(){
__int64 ans=0;
for(int i=1;i<=10000;i++){
E2 e2=calc(i);
if(e2.li.size()<=17){
ans+=to_num(e2.li)/i;
}else{
std::cout<<"\n"<<i<<" ";
e2.print();
}
if(i%400==0)std::cout<<i<<"\n";
}
std::cout<<ans<<"\n";
}
最終更新:2015年11月08日 06:07