Description
农民约翰的母牛总是生产出最好的肋骨。你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们。 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质数,举例来说: 7 3 3 1 全部肋骨上的数字 7331是质数;三根肋骨 733是质数;二根肋骨 73 是质数;当然,最后一根肋骨 7 也是质数。 7331 被叫做长度 4 的特殊质数。 写一个程序对给定的肋骨的数目 N (1< =N< =8),求出所有的特殊质数。数字1不被看作一个质数。
Input
单独的一行包含N。
Output
按顺序输出长度为 N 的特殊质数,每行一个。 并按大小顺序排列(从小到大).
Sample Input
4
Sample Output
2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393
Key To Problem
题目大意,求出n位数中前缀质数的数。
一道数列上的bfs的题,由于我比较蒟蒻,所以作法比较垃圾。
首先快筛出所有小于
104
的特殊质数,之后由这些质素为初始值进行宽搜,每次在原特定数字后加一个数字,形成一个新的数,若这个新生成的数是特殊质数,那么就可以将这个新生成的数加入队列。
Code
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 10010
#define M 6000000
using namespace std;
struct node
{
int u,deep;
};
int n,tot,cnt;
int prime[N];
int QT[1000];
bool used[N];
int ans[M];
bool cmp(int x,int y)
{
return x<y;
}
int sum(int x)
{
int s=0;
while(x)
{
x/=10;
s++;
}
return s;
}
bool kk(int x)
{
while(x)
{
x/=10;
if(used[x])
return false;
}
return true;
}
bool is(int x)
{
for(int i=1;prime[i]*prime[i]<=x;i++)
{
if(x%prime[i]==0)
return false;
}
return true;
}
void quick_prime()
{
used[1]=true;
for(int i=2;i<=10000;i++)
{
if(!used[i])
prime[++tot]=i;
for(int j=1;i*prime[j]<=10000&&j<=tot;j++)
{
used[i*prime[j]]=true;
if(i%prime[j]==0)
break;
}
}
int p=0;
for(int i=1;i<=tot;i++)
{
if(kk(prime[i]))
QT[++p]=prime[i];
}
tot=p;
}
void bfs(int u,int deep)
{
node k;
k.u=u,k.deep=deep;
queue<node>Q;
Q.push(k);
while(!Q.empty())
{
k=Q.front();
Q.pop();
if(k.deep==n)
{
ans[++cnt]=k.u;
continue;
}
for(int i=1;i<=9;i+=2)
{
int x=k.u*10+i;
if(is(x))
{
node p;
p.u=x,p.deep=k.deep+1;
Q.push(p);
}
}
}
}
int main()
{
quick_prime();
cin>>n;
if(n<=4)
{
int st,en;
for(int i=1;i<=tot;i++)
{
if(sum(QT[i])==n)
printf("%d\n",QT[i]);
}
return 0;
}
for(int i=28;i<=tot;i++)
bfs(QT[i],4);
sort(ans+1,ans+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
printf("%d\n",ans[i]);
return 0;
}