先曝上一道题:
ural 1343 Fairy Tale
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Description
12 months to sing and dance in a ring their celestial dance. One after another they hold a throne. The first is young and fierce January and the last is elderly and wise December. Leaving the throne, every month cry out a digit. During a year a 12-digit number is formed. The Old Year uses this number as a shield on his way to the Abyss of Time. He defend himself with this shield from the dreadful creatures of Eternity. Because of hard blows the shield breaks to pieces corresponding to the divisors of the number.
Your task is to help the months to forge the shield for the Old Year such that it couldn’t be broken to pieces.
Input
The first line contains a number of months that already left the throne. The second line contains the digits already cried out.
Output
Output an arbitrary 12-digits integer that starts with the given digits and that has no nontrivial divisors. It’s guaranteed that the solution exists.
Sample Input
input | output |
---|---|
5 64631 |
646310554187 |
这道题看起来挺白痴的,因为第一遍做的时候,直接暴力枚举,竟然就能通过了。
AC代码如下:
1 #include <iostream> 2 using namespace std; 3 4 bool isprime(long long a){ 5 if(a<2) return 0; 6 for(long long i=2;i*i<=a;i++){ 7 if(a%i==0) return 0; 8 } 9 return 1; 10 } 11 12 int main(){ 13 int n; 14 long long x,t; 15 cin>>n; 16 if(n){ 17 cin>>t; 18 } 19 else { 20 t=0; 21 } 22 23 x=t; 24 for(int i=n+1;i<=12;i++){ 25 x=x*10; 26 } 27 28 for(long long i=x;;i++){ 29 if(isprime(i)) { 30 printf("%012I64d ",i); 31 break; 32 return 0; 33 } 34 35 } 36 }
其实不然,细细想想如果碰到一个很大的区间都没有素数怎么办,那样的话,直接递增往后找的方法很容易超时。这时候,书本上素数分布定理就可以用得上了。
记π(x)为小于x的所有素数的个数,可以证明limx->正无穷 π(x)/(x/lnx)=1,这也就说明了一个现象,就是你如果随机测试一个大的n为数,它为素数的概率是可以预见的。
也就是说随机测试一个n位的数,总能在有限步骤内找到一个素数。事实上,经证明大概每找1.44个数,就能找到这样一个素数,这是很大的概率。 素数分布的这个性质,已经被广泛的应用于寻找n位大素数的工作,所以本题为了保证不超时,运用“随机生成的数”来测试是否为素数的方式会更加科学。
代码如下:
1 #include <iostream> 2 #include <ctime> 3 #include <algorithm> 4 using namespace std; 5 6 bool isprime(long long a){ 7 if(a<2) return 0; 8 for(long long i=2;i*i<=a;i++){ 9 if(a%i==0) return 0; 10 } 11 return 1; 12 } 13 14 int main(){ 15 int n; 16 long long x,t; 17 srand((unsigned)time(NULL)); 18 cin>>n; 19 if(n){ 20 cin>>t; 21 } 22 else { 23 t=0; 24 } 25 26 27 do{ 28 x=t; 29 for(int i=n;i<=11;i++){ 30 x=(x<<1)+(x<<3)+(long long)((rand()&15)%10); 31 } 32 }while(!isprime(x)); 33 34 printf("%012I64d ",x); 35 36 }
另外还有一些素数比较有趣的分布的特点这里也做一下梳理:
1.任意两个相邻的正整数n和n+1中必有一个不是素数。额,这倒不如说n,n+1必有一个是偶数,显然没什么卵用。
2.越往后越稀疏:在正整数序列中,有任意长的区间中不含有素数。
对于大于等于2的整数n,连续n-1个整数n!+2,n!+3,n!+4.....n!+n都不是素数。
3.n,n+2均为素数的例子有很多,这样的一对素数成为孪生素数。
目前孪生素数的证明,最好的证明是由张益唐提出的方法经过改进后的方法,这个距离已经缩小到246。
4.p为素数,2p-1称为梅森数,素数2p-1称为梅森素数。也就是说2p-1不一定是素数
5.形如4n+3的素数有无线多个。这一点,在另一篇博客:“威尔逊定理”中有提到。