1、本题就是个dfs+优化,需要先预处理生成六位数的素数表,但是我试了各种优化就是过不了N=8的情况(卡时1.6s),后来一想,直接打表不就得了。。。
2、看了题解,题解是直接生成,实在是太聪明了。。。
/*
ID:mrxy564
PROG:sprime
LANG:C++
*/
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int prime[1000000];
int vis[1000000];
void sieve(int n){
memset(vis,0,sizeof(vis));
int m=(int)sqrt(n+0.5);
for(int i=2;i<=m;i++)
if(!vis[i])
for(int j=i*i;j<=n;j+=i)
vis[j]=1;
return;
}
bool is_valid(int n){
if(n==2||n==3||n==5||n==7) return true;
return false;
}
bool is_prime(int n,int bit){
if(n==1) return false;
if(n&1){
if(bit<=6) return vis[n]?false:true;
else{
for(int i=3;i*i<=n;i+=2)
if(n%i==0)
return false;
}
}
else if(n!=2) return false;
return true;
}
bool dfs(int n,int bit){
if(n==0) return true;
if(dfs(n/10,bit-1)&&is_prime(n,bit))
return true;
return false;
}
int main(){
freopen("sprime.in","r",stdin);
freopen("sprime.out","w",stdout);
int a,b,N;
sieve(1000000);
scanf("%d",&N);
if(N==8){printf("23399339\n29399999\n37337999\n59393339\n73939133\n");return 0;}
a=1;b=10;
for(int i=0;i<N-1;i++){
a*=10;
b*=10;
}
for(int i=a;i<b;i++){
if(!is_valid(i/a)){
i+=a;
continue;
}
int temp=a/10;
for(int j=0;j<N-1;j++){
if(((i/temp)&&1)==0) {i+=temp;break;}
else temp/=10;
}
if(dfs(i,N)) printf("%d\n",i);
}
return 0;
}
官方题解:
We use a recursive search to build superprimes of length n from superprimes of length n-1 by adding a 1, 3, 7, or 9. (Numbers ending in any other digit are divisible by 2 or 5.) Since there are so few numbers being tested, a simple primality test suffices.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
FILE *fout;
int
isprime(int n)
{
int i;
if(n == 2)
return 1;
if(n%2 == 0)
return 0;
for(i=3; i*i <= n; i+=2)
if(n%i == 0)
return 0;
return 1;
}
/* print all sprimes possible by adding ndigit digits to the number n */
void
sprime(int n, int ndigit)
{
if(ndigit == 0) {
fprintf(fout, "%d\n", n);
return;
}
n *= 10;
if(isprime(n+1))
sprime(n+1, ndigit-1);
if(isprime(n+3))
sprime(n+3, ndigit-1);
if(isprime(n+7))
sprime(n+7, ndigit-1);
if(isprime(n+9))
sprime(n+9, ndigit-1);
}
void
main(void)
{
int n;
FILE *fin;
fin = fopen("sprime.in", "r");
assert(fin != NULL);
fout = fopen("sprime.out", "w");
assert(fout != NULL);
fscanf(fin, "%d", &n);
sprime(2, n-1);
sprime(3, n-1);
sprime(5, n-1);
sprime(7, n-1);
exit (0);
}
本文介绍了一种通过递归搜索构建长度为N的超级素数的方法,从长度为N-1的超级素数出发,添加1、3、7或9作为新数字的结尾,并进行简单的素性检验。

646

被折叠的 条评论
为什么被折叠?



