这是一道极度毒瘤的搜索题,考验代码能力,也考验耐心。
步入正题。这题题面说了,给出素数的各个数位上的和,要求所有素数的各个位数上的和必须相等,这对优化后来的搜索有极大帮助。第二个题面给出了左上角的数,又减少了一定的搜索量。
这题要求每行,每列,以及两条对角线上的数字得要是是五位的素数。(就是大于等于10000小于等于99999的素数)对于这个我们可以先用埃拉托色尼斯筛将10000到99999的所有素数找出来并记录。(线性筛也行,但影响不大,就90000个数)
老刘给的搜索顺序,写13重循环,但是我偏不。
我要这么搜
这题还有个比较毒瘤的是要求“按照这25个数字组成的25位数的大小排序”
从小到大排很简单,sort一下就好。
但是,显然用long long也存不下,这时就该派字符串上场了。我的方法是写了个函数,枚举25个点,将这25个点变为一个字符串。输出时注意一下换行就好了。
对于验证每一行的数是否是素数,我写了个检验函数,先将五个数字变为5位数,如果一开始筛完后那个数为素数就是true,否则就是false。
在13个for循环中还有很多优化,比如剩下的那个数如果小于0或者大于9就continue。
复杂点的是首位数字还有要加判断。
/// _ooOoo_
/// o8888888o
/// 88" . "88
/// (| -_- |)
/// O\ = /O
/// ____/`---'\____
/// .' \\| |// `.
/// / \\||| : |||// \
/// / _||||| -:- |||||- \
/// | | \\\ - /// | |
/// | \_| ''\---/'' | |
/// \ .-\__ `-` ___/-. /
/// ___`. .' /--.--\ `. . __
/// ."" '< `.___\_<|>_/___.' >'"".
/// | | : `- \`.;`\ _ /`;.`/ - ` : | |
/// \ \ `-. \_ __\ /__ _/ .-` / /
///======`-.____`-.___\_____/___.-`____.-'======
/// `=---='
///^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#include<bits/stdc++.h>
using namespace std;
#define f(a,b,c) for(int c=a;c<=b;c++)
#define so1(a,n,mycmp) sort(a+1,a+n+1,mycmp);
#define so2(a,n) sort(a+1,a+n+1);
#define ll long long
#define in cin
#define out cout
const int twx=100000+100;
int a11,tot;
int m=0;
int asd=0;
int f[6][6],last[5]={0,1,3,7,9},num=0;
string ans[twx];
bool check[twx];
bool dfg(int a,int b,int c,int d,int e)
{
int asd=a*10000+b*1000+c*100+d*10+e;
if(check[asd])
{
return true;
}
else
{
return false;
}
}
void primes()
{
memset(check,true,sizeof(check));
f(2,100000,i)
{
if(check[i])
{
f(i,100000/i,j)
{
check[i*j]=false;
}
}
}
return ;
/*f(2,n,i)
{
if(v[i]==0)
{
v[i]=i;
prime[++m]=i;
}
f(1,m,j)
{
if(prime[j]>v[i]||prime[j]>n/i)
{
break;
}
v[i*prime[j]]=prime[j];
}
}*/
/*f(1,m,i)
{
out<<prime[i]<<" ";
}*/
}
void init()
{
in>>tot>>a11;
}
void ghj()
{
num++;
f(1,5,i)
{
f(1,5,j)
{
ans[num]+=f[i][j]+48;
}
}
return ;
}
void work()
{
f(1,4,A)//f[5][5] 剪枝
{
f[5][5]=last[A];
f(0,9,B)//f[4][4]
{
f[4][4]=B;
f(0,9,C)//f[3][3]
{
f[3][3]=C;
f[2][2]=tot-f[1][1]-f[3][3]-f[4][4]-f[5][5];//f[2][2]可得出
if(f[2][2]<0)
{
break;
}
if(f[2][2]>9)
{
continue ;
}
if(!dfg(f[1][1],f[2][2],f[3][3],f[4][4],f[5][5]))
{
continue ;
}
f(1,4,D)//f[5][1]
{
f[5][1]=last[D];
f(1,4,E)//f[5][2]
{
f[5][2]=last[E];
f(1,4,F)//f[5][3]
{
f[5][3]=last[F];
f[5][4]=tot-f[5][1]-f[5][2]-f[5][3]-f[5][5];//f[5][4]可计算出
if(f[5][4]<0)
{
break;
}
if(f[5][4]>9)
{
continue ;
}
if(!dfg(f[5][1],f[5][2],f[5][3],f[5][4],f[5][5]))
{
continue ;
}
f(1,4,G)//f[1][5]
{
f[1][5]=last[G];
f(1,4,H)//f[2][5]
{
f[2][5]=last[H];
f(1,4,I)//f[3][5]
{
f[3][5]=last[I];
f[4][5]=tot-f[1][5]-f[2][5]-f[3][5]-f[5][5];//f[4][5]
if(f[4][5]<0)
{
break;
}
if(f[4][5]>9)
{
continue ;
}
if(!dfg(f[1][5],f[2][5],f[3][5],f[4][5],f[5][5]))
{
continue ;
}
f(0,9,J)//f[4][2]
{
f[4][2]=J;
f[2][4]=tot-f[5][1]-f[4][2]-f[3][3]-f[1][5];
if(f[2][4]<0)
{
break;
}
if(f[2][4]>9)
{
continue ;
}
if(!dfg(f[5][1],f[4][2],f[3][3],f[2][4],f[1][5]))
{
continue;
}
f(1,9,K)//f[1][4]
{
f[1][4]=K;
f[3][4]=tot-f[1][4]-f[2][4]-f[4][4]-f[5][4];
if(f[3][4]<0)
{
break;
}
if(f[3][4]>9)
{
continue ;
}
if(!dfg(f[1][4],f[2][4],f[3][4],f[4][4],f[5][4]))
{
continue ;
}
f(1,9,L)//f[1][3]
{
f[1][3]=L;
f[1][2]=tot-f[1][1]-f[1][3]-f[1][4]-f[1][5];
if(f[1][2]<=0)
{
break;
}
if(f[1][2]>9)
{
continue ;
}
if(!dfg(f[1][1],f[1][2],f[1][3],f[1][4],f[1][5]))
{
continue ;
}
f[3][2]=tot-f[1][2]-f[2][2]-f[4][2]-f[5][2];
if(f[3][2]<0||f[3][2]>9)
{
continue ;
}
if(!dfg(f[1][2],f[2][2],f[3][2],f[4][2],f[5][2]))
{
continue ;
}
f(1,9,M)//f[2][1]
{
f[2][1]=M;
f[2][3]=tot-f[2][1]-f[2][2]-f[2][4]-f[2][5];
if(f[2][3]<0)
{
break;
}
if(f[2][3]>9)
{
continue ;
}
if(!dfg(f[2][1],f[2][2],f[2][3],f[2][4],f[2][5]))
{
continue ;
}
f[4][3]=tot-f[1][3]-f[2][3]-f[3][3]-f[5][3];
if(f[4][3]<0||f[4][3]>9)
{
continue ;
}
if(!dfg(f[1][3],f[2][3],f[3][3],f[4][3],f[5][3]))
{
continue ;
}
f[4][1]=tot-f[4][2]-f[4][3]-f[4][4]-f[4][5];
if(f[4][1]<=0||f[4][1]>9)
{
continue ;
}
if(!dfg(f[4][1],f[4][2],f[4][3],f[4][4],f[4][5]))
{
continue ;
}
f[3][1]=tot-f[1][1]-f[2][1]-f[4][1]-f[5][1];
if(f[3][1]<=0||f[3][1]>9)
{
continue ;
}
if(!dfg(f[1][1],f[2][1],f[3][1],f[4][1],f[5][1]))
{
continue ;
}
if(!dfg(f[3][1],f[3][2],f[3][3],f[3][4],f[3][5]))
{
continue ;
}
ghj();
}
}
}
}
}
}
}
}
}
}
}
}
}
return ;
}
int main()
{
//freopen("input.in","r",stdin);
//freopen("output.out","w",stdout);
init();
f[1][1]=a11;
primes();
work();
so2(ans,num);//给字符串排序
f(1,num,i)
{
f(0,24,j)
{
printf("%c",ans[i][j]);
if((j+1)%5==0)
{
out<<endl;
}
}
out<<endl;
}
if(num==0)
{
out<<"NONE";
}
return 0;
}
其实这道题也没想象中的那么难,只是中间的13个for循环比较难写,但主要内容都是一样的。
考验代码能力。