The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.
Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.
质数3, 7, 109, 和 673是值得注意的。将其中任意两个质数以任何顺序相连接产生的结果都是质数。例如,取7和109,连接而成的7109和1097都是质数。这四个质数的和是792,这也是满足这个性质的四个质数集合的最小总和。
找出满足这个性质的五个质数的集合中,集合数之和最小的。算出这个最小的和。
#include<iostream> #include<stdio.h> #include<set> #include<map> #include<algorithm> using namespace std; const int limit=100000001; bool bprime[limit]= {0}; int prime[11010],nprime=0; struct Edge { int x,y; bool operator < (const Edge & b) const { return this->x < b.x; } Edge(int a=0,int b=0):x(a),y(b) {} } data[40000]; int cnt=0; int check(int a,int b,int c,int d,int e) { int num[5]= {a,b,c,d,e}; for(int i=0; i<5; i++) for(int j=0; j<5; j++) { if(i==j) continue; int tmp=num[i]; int ans=num[j]; while(tmp) { ans*=10; tmp/=10; } ans+=num[i]; if (ans>=limit||bprime[ans]) return false; } return true; } bool bingo(int ary[],int n) { int a=0; for(int b=a+1; b<n; b++) for(int c=b+1; c<n; c++) for(int d=c+1; d<n; d++) for(int e=d+1; e<n; e++) if(check(ary[a],ary[b],ary[c],ary[d],ary[e])) { cout<<ary[a]<<" "<<ary[b]<<" "<<ary[c]<<" "<<ary[d]<<" "<<ary[e]<<endl; cout<<ary[a]+ary[b]+ary[c]+ary[d]+ary[e]<<endl; return true; } return false; } bool ok(int a,int b) { int tmp=a,n=b; while(n) { tmp*=10; n/=10; } tmp+=b; if(bprime[tmp]) return false; tmp=b,n=a; while(n) { tmp*=10; n/=10; } tmp+=a; return !bprime[tmp]; } set<int> se; int main() { //freopen("out.txt","w",stdout); bprime[0]=bprime[1]=true; for(int i=2; i<10000; i++) if(!bprime[i]) for(int j=i<<1; j<limit; j+=i) bprime[j]=true; for(int i=2; i<limit; i++) if(!bprime[i]&&i<10000) prime[nprime++]=i; int ans=0; for(int i=0; i<nprime; i++) for(int j=i+1; j<nprime; j++) if(ok(prime[i],prime[j])) { data[cnt++]=Edge(prime[i],prime[j]); data[cnt++]=Edge(prime[j],prime[i]); } sort(data,data+cnt); int i=0; int ary[400],n; while(i<cnt) { se.clear(); int x=data[i].x; se.insert(x); while(data[i].x==x) se.insert(data[i++].y); n=0; for(set<int>::const_iterator it=se.begin(); it!=se.end(); ++it) ary[n++]=*it; if(bingo(ary,n)) return 0; } return 0; } /*** 13 5197 5701 6733 8389 26033 about 9 seconds ***/