PE刷题记录

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\n",qsum);
	return 0;
}
在我的机子上都要跑0.7s+,-O2.我猜不用vector可能会好些.
posted @ 2015-06-19 20:57  zball  阅读(429)  评论(2编辑  收藏  举报