题解 P1218 【[USACO1.5]特殊的质数肋骨 Superprime Rib】
题目要我们求长度为n的特殊质数。
首先长度为n的特殊质数肯定建立在长度为n-1的特殊质数上才符合条件。
于是我们先求出长度为1的质数,再在这个质数上枚举加上0~9的数字,判断是不是质数,以此来得到长度为2的特殊质数。
以此类推,可以得到长度为3的、长度为4的、一直到n。
循环枚举模拟,暴力判断是否为质数即可。
复杂度讲道理是不高的。因为从长度为1开始这种质数就很少嘛。
其它的质数判断就不多讲啦~
下面是代码。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int pri[N],p; //现有的质数
int npri[N],np; //新处理的质数
inline bool ispri(int x){
if(x==0||x==1) return false;
for(int i=2;i*i<=x;i++)
if(x%i==0) return false;
return true;
} //暴力判断是否为质数
int main(){
int n;
cin>>n;
p=1; //初始化时长度为0,即由数字0推得长度为1的特殊质数
for(int i=1;i<=n;i++){
np=0;
for(int j=0;j<p;j++)
for(int k=0;k<=9;k++) //枚举质数和新加上的数字
if(ispri(pri[j]*10+k))npri[np++]=pri[j]*10+k; //若i-1长度的质数加上了该数字仍是质数,则放入新的i长度的质数数组当中。
memcpy(pri,npri,sizeof(npri)); //复制数组
p=np;
}
for(int i=0;i<p;i++) printf("%d\n",pri[i]);
return 0;
}