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
***/