sprime解题报告 —— icedream61 博客园(转载请注明出处)
------------------------------------------------------------------------------------------------------------------------------------------------
【题目】
列出所有N位的超级素数。
所谓超级素数,即指其任意位前缀均为素数。例如7、73、733、7331均为素数,故而7331为超级素数。
【数据范围】
1<=N<=8
【输入样例】
4
【输出样例】
2333
2339
2393
2399
2939
3119
3137
3733
3739
3793
3797
5939
7193
7331
7333
7393
------------------------------------------------------------------------------------------------------------------------------------------------
【分析】
逐位枚举+筛法+试除法。
这道题需要逐位枚举,具体过程描述如下:
1.定义0位的素数只有0(为了编程方便),调用函数go(0,0);
2.函数go(k,x)主体:x是k位的超级素数,枚举y=x*10+i(i=0~9),由筛法所得数组判断,若y为超级素数则调用go(k+1,y);
3.函数go(k,x)边界:当k==N时,输出x并return;
4.函数go(k,x)特判(置于边界判断后):当k==7&&N==8时,枚举y=x*10+i(i=0~9),由试除法判断,若y为超级素数则调用go(k+1,y);
值得一提的是,这里的特判可以大大提高运行效率,大约从2s缩减到0.2s,性价比很高。
------------------------------------------------------------------------------------------------------------------------------------------------
【总结】
又是同样的问题,好奇怪!为什么100,000,000过不了?求解答啊!
我的处理方法是:令max=10,000,000,对于N==8的情况,在枚举到第8位的时候采用试除法判素数。这样便可以过了。
不过这样的处理倒是很不错的,因为这样一来筛法的时间变成了十分之一,而到8位可枚举的数已经少之又少,所以程序的运行效率提高极为显著。原来代码运行时间是2s+,现在只有不到0.2s了。学习了!
------------------------------------------------------------------------------------------------------------------------------------------------
【代码】
1 /* 2 ID: icedrea1 3 PROB: sprime 4 LANG: C++ 5 */ 6 7 #include <iostream> 8 #include <fstream> 9 #include <cmath> 10 using namespace std; 11 12 const int maxd = 10000000; 13 bool d[1+maxd]; 14 15 int N; 16 17 bool isPrime(int x) 18 { 19 for(int i=2;i<=sqrt(x);++i) 20 if(x%i==0) return false; 21 return true; 22 } 23 24 void go(int k,int x,ofstream &out) 25 { 26 if(k==N) { out<<x<<endl; return; } 27 x*=10; 28 if(N==8 && k==7) 29 { 30 for(int i=0;i<=9;++i) 31 if(isPrime(x+i)) go(k+1,x+i,out); 32 return; 33 } 34 for(int i=0;i<=9;++i) 35 if(!d[x+i]) go(k+1,x+i,out); 36 } 37 38 int main() 39 { 40 ifstream in("sprime.in"); 41 ofstream out("sprime.out"); 42 43 d[0]=d[1]=true; 44 for(int i=1;i<=10000;++i) 45 if(!d[i]) 46 for(int j=i+i;j<=maxd;j+=i) d[j]=true; 47 48 in>>N; 49 50 go(0,0,out); 51 52 in.close(); 53 out.close(); 54 return 0; 55 }