题目描述
如果一个质数,在质数列表中的编号也是质数,那么就称之为质数中的质数。例如:3 5分别是排第2和第3的质数,所以他们是质数中的质数。现在给出一个数N,求>=N的最小的质数中的质数是多少(可以考虑用质数筛法来做)。
Input
输入一个数N(N <= 10^6)
Output
输出>=N的最小的质数中的质数。
Input示例
20
Output示例
31
这个题当时做的时候,觉得10^6=100000 然后一直wa,找不到wa点,交了两发后重看题目信息才改过来,一改数据范围就对了….惊了.
由题干信息得我们需要先知道有哪些数时质数,然后我们需要求出哪些在质数中的数他们的排列也是质数
所以首先需要一个数组存哪些数是质数,第二个表依次存入质数,第三个表存入第二个表的素数他的位置是不是素数,最后输出的时候如果vis2[i]>=n&&vis3[i]==0就可以输出这个结果(注意这里的等于号!!)
但是这里实际上不需要这么多数组,先贴代码,下面说
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int MAX_N=100000;
int vis[1001010];
int vis2[1001010];
int vis3[1001010];
int main()
{
ios::sync_with_stdio(false);
memset(vis,0,sizeof(vis));
memset(vis2,0,sizeof(vis2));
memset(vis3,0,sizeof(vis3));
vis[1]=1;
ll qq=1;
for(ll i=2;i<1001010;i++){
if(!vis[i])
for(ll j=i*2;j<=1001010;j=j+i)
vis[j]=1;
if(vis[i]==0)
vis2[qq++]=i;
}
for(ll i=2;i<qq;i++){
for(int w=i*2;w<=qq;w=w+i)
vis3[w]=1;
}
int n;
vis3[1]=1;
while(cin>>n){
int flag=0;
for(int i=1;i<=qq&&flag==0;i++)
if(vis2[i]>=n&&vis3[i]==0){
flag=1;
cout<<vis2[i]<<endl;
}
}
return 0;
}
这个代码用时46ms 内存占用13.6m
那么该怎么优化呢,首先vis数组起到的是标记一个数是不是素数,所以完全可以换成占用更小内存的bool类型
其次vis3数组的存在真的有必要吗,他仅仅就是查询这个数的位置是不是素数,完全可以用vis这个表来代替,可以删去,而且1000000的多次初始化 可能还会导致时间增加
优化代码如下:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int MAX_N=100000;
bool vis[1001010];
int vis2[1001010];
int n;
int main()
{
ios::sync_with_stdio(false);
memset(vis,0,sizeof(vis));
memset(vis2,0,sizeof(vis2));
vis[1]=1;
ll qq=1;
for(ll i=2;i<1001010;i++){
if(!vis[i])
for(ll j=i*2;j<=1001010;j=j+i)
vis[j]=1;
if(vis[i]==0)
vis2[qq++]=i;
}
while(cin>>n){
int flag=0;
for(int i=1;i<=qq&&flag==0;i++)
if(vis2[i]>=n&&vis[i]==0){
flag=1;
cout<<vis2[i]<<endl;
}
}
return 0;
}
这份代码的时间为31ms,占用内存降到了6.7m,如果还是想优化的话,可能就需要牺牲时间来减小内存了,比如不打素数表,依次判断这个数是不是素数,如果是就存入vis2数组,然后可以自己测试一下1000000内有几个素数,然后对数组大小进行优化,同级里有一位小兄弟采用了这种方法,内存占用降到了2m,但是时间耗时为472ms,所以可以说是得不偿失,这里就不再贴代码了