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