hdu1979

/*
分析:
    模拟题,水,1Y。
    很容易想到先求出满足条件的素数,有200+;单纯暴力枚举的话
就是200*200*200*200;
    不过也很容易看出来有很多可以优化的地方,枚举出两行的时候
判断下、枚举出三行的时候再判断下,又加入了部分静态临界表的优
化,这样就活生生的只进行了70多W次枚举出4行后的判断。
    前天晚上两点碰到这个题,各种嫌优化麻烦、又不想暴力打表,
就干脆睡觉了,今儿才又拿起来,囧~~。。代码不长也不算短、本着
恶趣味的心态贴一下 ^ ^ ~

                                                       2013-06-18
*/





#include"iostream"
#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int N=10005;
const int M=1005;

int prime[N],prime2[N];
int ans,cnt,ok[M],bas[M][4],map[4][4];
int hash2[10][10],hash3[10][10][10];
struct node{
	char str[20],map[4][5];
}E[10*N];

struct Edge{
	int v,next;
}edge[M];
int tot,head[10];
void add(int a,int b){
	edge[tot].v=b;edge[tot].next=head[a];head[a]=tot++;
}

void build_map()
{
	int i,l;
	tot=0;
	memset(head,-1,sizeof(head));
	for(i=0;i<10;i++)
	for(l=0;l<cnt;l++)
		if(bas[l][0]==i)	add(i,l);
}
void init()
{
	int i,l,t,temp;
	memset(prime,-1,sizeof(prime));
	memset(prime2,0,sizeof(prime2));
	prime[0]=prime[1]=0;
	for(i=2;i<10000;i++)
	{
		if(!prime[i])	continue;
		for(l=2*i;l<10000;l+=i)
			prime[l]=0;
	}
	int cnt0,hehe[M];
	cnt0=0;
	for(i=1000;i<10000;i++)
	{
		if(!prime[i])	continue;
		temp=0;
		t=i;
		while(t)	{temp=temp*10+t%10;t/=10;}
		if(prime[temp])	hehe[cnt0++]=i;
	}
	sort(hehe,hehe+cnt0);
	cnt=1;
	ok[0]=hehe[0];
	for(i=1;i<cnt0;i++)
	{
		if(hehe[i]==hehe[i-1])	continue;
		ok[cnt++]=hehe[i];
	}
	memset(hash2,0,sizeof(hash2));
	memset(hash3,0,sizeof(hash3));
	for(i=0;i<cnt;i++)
	{
		l=3;
		t=ok[i];
		prime2[ok[i]]=1;
		while(l>=0)	{bas[i][l]=t%10;t/=10;l--;}
		hash2[bas[i][0]][bas[i][1]]=1;
		hash3[bas[i][0]][bas[i][1]][bas[i][2]]=1;
	}
	build_map();
}

int cmp(node n1,node n2)
{
	int t=strcmp(n1.str,n2.str);
	return t<=0;
}
void solve()
{
	int i,l,z,k,j[4];
	int v0,v1,v2,ts=0,t1,t2,flag;
	ans=0;
	for(i=0;i<cnt;i++)
	{
		for(j[0]=head[bas[i][0]];j[0]!=-1;j[0]=edge[j[0]].next)
		{
			v0=edge[j[0]].v;
			for(j[1]=head[bas[i][1]];j[1]!=-1;j[1]=edge[j[1]].next)
			{
				v1=edge[j[1]].v;
				if(!hash2[bas[v0][0]][bas[v1][1]])	continue;
				if(!hash2[bas[v0][1]][bas[v1][1]])	continue;
				if(!hash2[bas[v0][2]][bas[v1][2]])	continue;
				if(!hash2[bas[v0][3]][bas[v1][3]])	continue;
				for(j[2]=head[bas[i][2]];j[2]!=-1;j[2]=edge[j[2]].next)
				{
					v2=edge[j[2]].v;
					if(!hash3[bas[v0][0]][bas[v1][1]][bas[v2][2]])	continue;
					if(!hash3[bas[v0][1]][bas[v1][1]][bas[v2][1]])	continue;
					if(!hash3[bas[v0][2]][bas[v1][2]][bas[v2][2]])	continue;
					if(!hash3[bas[v0][3]][bas[v1][3]][bas[v2][3]])	continue;
					for(j[3]=head[bas[i][3]];j[3]!=-1;j[3]=edge[j[3]].next)
					{
						for(l=0;l<4;l++)for(z=0;z<4;z++)map[l][z]=bas[edge[j[l]].v][z];
						flag=0;
						for(l=0;l<4;l++)
						{
							t1=0;
							for(z=0;z<4;z++)	t1=t1*10+map[z][l];
							if(!prime2[t1])	{flag=1;break;}
						}
						if(!flag)
						{
							t1=t2=0;
							for(z=0;z<4;z++)
							{
								t1=t1*10+map[z][z];
								t2=t2*10+map[z][3-z];
							}
							if(!prime2[t1] || !prime2[t2])	flag=1;
						}
						if(flag)	continue;
						k=0;
						for(l=0;l<4;l++)
						{
							for(z=0;z<4;z++)
							{
								E[ans].str[k++]=map[l][z]+'0';
								E[ans].map[l][z]=map[l][z]+'0';
							}
							E[ans].map[l][z]=0;
						}
						E[ans++].str[k]=0;
					}
				}
			}
		}
	}
	sort(E,E+ans,cmp);

	for(l=0;l<4;l++)	printf("%s\n",E[0].map[l]);
	for(i=1;i<ans;i++)
	{
		printf("\n");
		for(l=0;l<4;l++)	printf("%s\n",E[i].map[l]);
	}
}
int main()
{
	init();
	solve();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值