PE刷题记录
PE60 / 20%dif
这道题比较坑爹.所有可以相连的素数可以构成一张图,建出这张图,在其中找它的大小为5的团.注意上界的估算,大概在1W以内.1W内有1229个素数,处理出这些素数的关系,然后dfs这张图找出大小为5的团.
/*** * @name Prime pair sets * @author zball * @algorithm Sieve for primes and dfs search for finding a set of primes */ #include <cstdio> #include <vector> #include <algorithm> #define maxn 100000000 #define maxq 10000000 #define loop(i,f,t) for(int i=f;i<t;++i) using namespace std; struct nod{ vector<int> n; } node[1400]; #define nodes node bool isp[maxn]; int p[maxq],pl; void sieve(){ for(int i=2;i<maxn;++i){ if(!isp[i]) p[pl++]=i; for(int j=0;j<pl;++j){ int k=p[j]; if(i*k>=maxn) break; isp[i*k]=1; if(!(i%k)) break; } } } int u[maxq]; void constructLUT(){ loop(i,1,10) u[i]=10; loop(i,10,100) u[i]=100; loop(i,100,1000) u[i]=1000; loop(i,1000,10000) u[i]=10000; loop(i,10000,100000) u[i]=100000; loop(i,100000,1000000) u[i]=1000000; loop(i,1000000,10000000) u[i]=10000000; } inline bool isok(int n,int m){ n=p[n],m=p[m]; return !isp[u[n]*m+n]; } inline void ins(int n,int m){ node[n].n.push_back(m); node[m].n.push_back(n); } inline void constructGraph(int ma){ loop(i,0,ma){ loop(j,i+1,ma) if(isok(i,j)&&isok(j,i)) ins(i,j); } } int uu[10],ul; #define dep 4 #define depm1 3 int dfs(int n,int d,int su){ int mi=0x7fffffff,q=nodes[n].n.size(),mix; loop(i,0,d){ if((!isok(uu[i],n)) || (!isok(n,uu[i]))) return 0x7fffffff; } su+=p[n]; uu[d]=n; if(d==dep) return su; loop(i,0,q){ if(nodes[n].n[i]<n) continue; mix=dfs(nodes[n].n[i],d+1,su); if(mix<mi){ mi=mix; if(d==depm1) break; } } return mi; } int getGraph(int f,int t){ int mi=0x7fffffff,mix; loop(i,f,t){ mix=dfs(i,0,0); if(mix<mi) mi=mix; } return mi; } int main(){ sieve(); constructLUT(); constructGraph(1229); int qsum=getGraph(0,10); printf("%d ",qsum); return 0; }