题目描述 Description
农民约翰的母牛总是产生最好的肋骨。 你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们。 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质数,举例来说: 7 3 3 1 全部肋骨上的数字 7331是质数;三根肋骨 733是质数;二根肋骨 73 是质数;当然,最后一根肋骨 7 也是质数。 7331 被叫做长度 4 的特殊质数。 写一个程序对给定的肋骨的数目 N(1<=N<=8),求出所有的特殊质数。 数字1不被看作一个质数。
输入描述 Input Description
单独的一行包含N。
输出描述 Output Description
按顺序输出长度为 N 的特殊质数,每行一个。
样例输入 Sample Input
4
样例输出 Sample Output
2333 2339 2393 2399 2939 3119 3137 3733 3739 3793 3797 5939 7193 7331 7333 7393
数据范围及提示 Data Size & Hint
见描述
解1:暴搜判质数
TLE,即使加上记忆化也不行,最多60分。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 int n; 8 bool pmark[100000010]; 9 bool pd(int x){ 10 if(pmark[x])return false; 11 int tmp=sqrt(x); 12 for(int i=2;i<=tmp;i++){ 13 if(x%i==0){pmark[x]=1;return false;}; 14 } 15 return true; 16 } 17 int main(){ 18 scanf("%d",&n); 19 int st=pow(10,(n-1)); 20 int ed=(pow(10,n)-1); 21 bool flag=0; 22 for(int i=st;i<=ed;i++){ 23 //if(!(i&1))continue; 24 int tmp=i; 25 flag=0; 26 while(tmp){ 27 if(!(tmp&1)){ 28 flag=1;break; 29 } 30 if((tmp==1) ||pd(tmp)==false){ 31 flag=1; 32 break; 33 } 34 tmp/=10; 35 } 36 if(flag)continue; 37 printf("%d ",i); 38 } 39 return 0; 40 }
解2:枚举质数可能的组成。
质数的个位只有2 3 5 7四种可能,高位只有1 3 7 9四种可能。
这样每层搜索只枚举4个数,飞速出解。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 int p1[4]={2,3,5,7}; 8 int p2[4]={1,3,7,9}; 9 int n; 10 bool pd(int x){ 11 int tmp=sqrt(x); 12 for(int i=2;i<=tmp;i++) 13 if(x%i==0)return false; 14 return true; 15 } 16 void dfs(int s,int i){ 17 if(i==n){ 18 printf("%d ",s); 19 return; 20 } 21 int tmp; 22 for(int j=0;j<4;j++){ 23 tmp=s*10+p2[j]; 24 if(pd(tmp))dfs(tmp,i+1); 25 } 26 return; 27 } 28 int main(){ 29 scanf("%d",&n); 30 for(int i=0;i<4;i++) dfs(p1[i],1); 31 return 0; 32 }