您的位置:首页 > 编程语言 > C语言/C++

详细注释如何用C语言生成回文数的方法高效判断回文质数

2017-10-17 13:44 766 查看

Problem L

回文质数

时限:1000ms 内存限制:10000K 总时限:3000ms

描述:

因为151既是一个质数又是一个回文数(从左到右和从右到左看是一样的),所以151是回文质数.

写一个程序来找出范围[a,b](5<=a<b<=100,000,000)间的所有回文质数.
输入:

第一行 两个整数:a和b.
输出:

输出一个回文质数的列表,一行一个.
输入样例:

5 500
输出样例:

5
7
11
101
131
151
181
191
313
353
373
383
判断回文质数这道题目看起来很普通,似乎只需要依次判断一个数是否是回文数和素数即可,但是我们会发现,按照那个思路在编写程序时,会耗费大量的时间和空间,并且造成严重的超时问题,所以我不得不另辟蹊径,由于在该题的取值范围内回文数的数量是有限的,所以我们不妨用翻转一个整数生成回文数的方法,这样以来就可以将100000000范围缩小至10000,使程序具有更高的效率。经过数学分析,可得到除了11外所有位数为偶数的回文数都不是质数,故我们只需生成具有奇数位数的回文数,再判断它是否是质数即可。

#include<stdio.h>
#include<math.h>
int f(int n);
int g(int n);
int main()
{
int a,b,i,n;
scanf("%d%d",&a,&b);
if(a<12)//考虑到“11”的特殊性,需要分类讨论。
{
if(b<12)//a,b均小于11时,输出两者之间的质数即可
{
for(i=a;i<=b;i++)
{
if(f(i)==1)
printf("%d\n",i);
}
   }
   if(b>=12)//a小于11,b大于11时,输出a与11间的所有质数,然后生成大于11不大于b的所有偶数位回文数,判断其是否为质数
   {
    for(i=a;i<12;i++)
{
if(f(i)==1)
printf("%d\n",i);
}
goto L;
   }
    }
    if(a>=12)//a大于11时,只需生成a与b之间的所有回文质数,并判断是否为质数即可。
    {
L:   for(i=10;i<10000;i++)
  {
n=g(i);
if(n<a)continue;//判断n是否小于a,若小于a,则循环继续。
if(n>b)break;//判断n是否大于b,若成立,则循环结束。
else if(f(n)==1)
printf("%d\n",n);
  }
    }
return 0;
}
int f(int n)//判断n是否为素数的函数
{
int k;
if(n==2)return 1;
if(n%2==0&&n!=2)
{
return 0;
   }
    for(k=3;k<=sqrt(n);k=k+2)//将范围缩小到根号n可提高程序运行效率。
    { 
    if(n%k==0)
    return 0;
    }
    return 1;
}
int g(int n)//生成回文数的函数
{
int i,j,m,sum=0;
j=n;
n=n/10;//使其生成奇数位回文数
while(n!=0)
{
i=n%10;
n=n/10;
sum=sum*10+i;
j=10*j;
}
m=sum+j;
return m;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息