Section 4.3 prime

/*
ID: niepeng1
PROG: prime3
LANG: C++
*/
/*
 无比复杂,无比复杂。
 就是取出所有的纯奇数位组成的素数放到边界,然后
 就是枚举了.

*/
#include<stdio.h>
#include<memory.h>
#include<algorithm>
struct node
{
 char info[40];
}ans[1000];
bool notprime[100000],isprime[10][10][10][10][10],last[10]={0,1,0,1,0,0,0,1,0,1};
int prime[8400],i,j,k,l,s,n,temp[6],sp[11],lprime[8400],map[5][5],num;
inline int maxn(int x,int y)
{
 return x>y?x:y;
}
bool cmp(node s,node t)
{
 return strcmp(s.info,t.info)<0;
}
void getans()
{
 int i,j;
 num++;
 for (i=0;i<5;i++)
 {
  for (j=0;j<5;j++)
   ans[num].info[i*6+j]=map[i][j]+'0';
  ans[num].info[(i+1)*6-1]='/n';
 }
 ans[num].info[30]=0;
}
void oper()
{
 int i,j,t,r,p,q,o,k,l,m;
 for (i=sp[map[0][0]];i<sp[map[0][0]+1];i++)
  if (prime[i]%10==map[4][4])
  {
   t=prime[i]/10;
   for (k=3;k>=1;k--) {map[k][k]=t%10;t/=10;}
   for (j=sp[map[4][0]];j<sp[map[4][0]+1];j++)
    if (prime[j]%10==map[0][4]&&(prime[j]%1000)/100==map[2][2])
    {
     map[1][3]=(prime[j]%100)/10;map[3][1]=(prime[j]/1000)%10;
     p=map[1][1]+map[1][3]+map[1][4];
     for (map[1][0]=maxn(1,s-p-9);map[1][0]<=9&&map[1][0]<=s-p;map[1][0]++)
      if (isprime[map[1][0]][map[1][1]][s-p-map[1][0]][map[1][3]][map[1][4]])
      {
       map[1][2]=s-p-map[1][0];
       t=map[0][0]+map[1][0]+map[4][0];
       r=map[3][1]+map[3][3]+map[3][4];
       q=map[1][2]+map[2][2]+map[4][2];
       for (map[3][0]=maxn(maxn(maxn(1,s-t-9),s-r-9),q+1-r);map[3][0]<=9&&map[3][0]<=s-t-1&&map[3][0]<=s-r&&map[3][0]<=9+q-r;map[3][0]++)
        if (isprime[map[0][0]][map[1][0]][s-t-map[3][0]][map[3][0]][map[4][0]]
        &&isprime[map[3][0]][map[3][1]][s-r-map[3][0]][map[3][3]][map[3][4]]
        &&isprime[r-q+map[3][0]][map[1][2]][map[2][2]][s-r-map[3][0]][map[4][2]])
        {
         map[2][0]=s-t-map[3][0];map[3][2]=s-r-map[3][0];map[0][2]=r-q+map[3][0];
         o=map[1][1]+map[3][1]+map[4][1];
         k=map[0][0]+map[0][2]+map[0][4];
         l=map[1][3]+map[3][3]+map[4][3];
         m=map[2][0]+map[2][2]+map[2][4];
         if (o+l!=k+m) continue;
         for (map[0][1]=maxn(maxn(maxn(1,s-o-9),s-k-9),l-k);map[0][1]<=9&&map[0][1]<=s-o&&map[0][1]<=s-k&&map[0][1]<=9+l-k;map[0][1]++)
          if (isprime[map[0][0]][map[0][1]][map[0][2]][s-k-map[0][1]][map[0][4]]
          &&isprime[map[0][1]][map[1][1]][s-o-map[0][1]][map[3][1]][map[4][1]]
          &&isprime[s-k-map[0][1]][map[1][3]][k+map[0][1]-l][map[3][3]][map[4][3]]
          &&isprime[map[2][0]][s-o-map[0][1]][map[2][2]][k+map[0][1]-l][map[2][4]])
          {
           map[0][3]=s-k-map[0][1];map[2][1]=s-o-map[0][1];map[2][3]=k+map[0][1]-l;
           getans();
          }
        }
      }
    }
  }
}
int main()
{
 freopen("prime3.in","r",stdin);
 freopen("prime3.out","w",stdout);
 scanf("%d%d",&s,&n);
 memset(notprime,false,sizeof(notprime));
 memset(isprime,false,sizeof(isprime));
 prime[0]=0;lprime[0]=0;
 for (i=1;i<10;i++) sp[i]=8000;
 for (i=2;i<100000;i++)
  if (notprime[i]==false)
  {
   if (i<=316) for (j=i*i;j<100000;j+=i) notprime[j]=true;
   if (i>10000)
   {
    k=i;temp[0]=0;
    while (k)
    {
     temp[++temp[0]]=k%10;
     k/=10;
    }
    if (s==temp[1]+temp[2]+temp[3]+temp[4]+temp[5])
    {
           prime[++prime[0]]=i;
     if (prime[0]<sp[temp[5]]) sp[temp[5]]=prime[0];
     isprime[temp[5]][temp[4]][temp[3]][temp[2]][temp[1]]=true;
     if (last[temp[5]]&&last[temp[4]]&&last[temp[3]]&&last[temp[2]]&&last[temp[1]]) lprime[++lprime[0]]=i;
    }
   }
  }
 num=-1;
 sp[10]=prime[0]+1;
 map[0][0]=n;
 for (i=1;i<=lprime[0];i++)
  for (j=1;j<=lprime[0];j++)
   if (lprime[i]%10==lprime[j]%10)
   {
    k=lprime[i];
    for (l=4;l>=0;l--) {map[4][l]=k%10;k/=10;}
    k=lprime[j]/10;
    for (l=3;l>=0;l--) {map[l][4]=k%10;k/=10;}
    oper();
   }
 std::sort(ans,ans+num+1,cmp);
 if (num==-1) printf("NONE/n");
 else
  for (i=0;i<=num;i++)
  {
   if (i) printf("/n");
   printf("%s",ans[i].info);
  }
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值