<Sicily>Prime Palindromes

一、题目描述

The number 151 is a prime palindrome because it is both a prime number and a palindrome (it is the same number when read forward as backward). Write a program that finds all prime palindromes in the range of two supplied numbers a and b (5 <= a < b <= 100,000,000); both a and b are considered to be within the range .

二、输入

There are multiple test cases.

Each case contains two integers, a and b.

a=b=0 indicates the end of input.

三、输出

For each test case, output the list of palindromic primes in numerical order, one per line.

例如:
输入:
5 500
0 0
输出:
5
7
11
101
131
151
181
191
313
353
373
383

四、解题思路

题意:输入两个数a和b,找出a-b之间的所有既是质数,又是回文数。当a = b = 0是退出。

思路:这道题看似简单,只需要找出a到b之间的质数,然后从中找出是回文数就OK了。可是题目有一个要求程序运行时间不能超过1秒,而且a,b的范围达到5-100,000,000,很容易超时,所以求质数要用最快的方法。我在这个超时上折腾了好长时间,差不多有两个小时。

1、判断是否是回文数
要判断数i是否是回文数,每一次操作不断地对其求取10的余数,产生新的数对原来的数进行翻转,翻转后的数跟原来的数比较,看是否相等,如果相等是回文数否则不是。如下图:
这里写图片描述
这里写图片描述

int num = i;
int temp = 0;
 while(num)
 {
     temp *= 10;
     temp += num%10;
     num /= 10;
 }

2、判断是否是质数
有一个定理:如果一个数是合数,那么它的最小质数肯定小于等于的二次方根。
按照以上定理,如果一个数能被它的最小质因数整除,那它是合数,即不是质数。所以判断一个数是否是质数,只需判断它是否能被小于它开根号后的所有数整除,这样做的运算练少很多从而提高了效率。

3、使用筛法求质数,用内存换时间
先建立一个boolean类型的数组,用来存储你要判断某个范围内自然数中的质数,例如,你要输出小于10000005的质数,你需要建立一个大小为10000005(建立10000005个存储位置是为了让数组位置与其大小相同)的boolean数组,初始化为true。是偶数的都不是质数。
  其次用以上的方法求的第一个质数(例如3),然后将是3的倍数的数全置为false(2除外)位置上置为false。然后是3的倍数的全置为false(3除外),一直到10000005平方根,这样的话把不是质数的位置上置为false了,剩下的全是质数了

4、用一个大的数组保存
再求出其中是回文数的部分就是我们需要找的,再根据输入的a,b值,在数组中找出在a,b之间满足要求的回文质数。

五、代码

#include<iostream>
#include<math.h>

using namespace std;

#define maxn 10000005
bool isPrimeList[maxn];     //存放质数
int palindromeList[maxn];       //存放回文数

int main()
{
    int i;
    isPrimeList[0] = false;
    isPrimeList[1]= false;
    isPrimeList[2] = true;

    for(i = 3; i < maxn; i+=2)  //初始化质数
    {
        isPrimeList[i] = true;
        isPrimeList[i+1] = false;   //偶数不是质数
    }

    int n = sqrt(maxn);     //通过开根号求质数
    for(i = 3; i < n; i+= 2)
    {
        if(!isPrimeList[i]) continue;
        for(int j = i; j*i < maxn; j++)
        {
            isPrimeList[j*i] = false;
        }
    }

    int palCount = 0;
    for(i = 0; i < maxn; i++)   //求回文数组
    {
        int num = i;
        int temp = 0;
        while(num)  //求num的翻转数
        {
            temp *= 10;
            temp += num%10;
            num /= 10;
        }
        if(i == temp && isPrimeList[i]) //这个回文数又是质数
        {
            palindromeList[++palCount] = i;
        }
    }

    int low, high;
    cin >> low >> high;
    while(low || high)
    {
        for(i = 0; palindromeList[i] < low; i++)
            continue;

        for(;palindromeList[i]<= high && palindromeList[i]!=0;i++)
            cout<<palindromeList[i]<<endl;

        cin >> low >> high;
    }

    return 0;
}
<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值