USACO 1.5.2 Prime Palindromes 回文质数

Description

因为151即是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 号是回文质数。写一个程序来找出范围[a,b](5 <= a < b <= 100,000,000)间的所有回文质数;

Input

第 1 行: 二个整数 a 和 b

Output

输出一个回文质数的列表,一行一个。

Sample Input

5 500

Sample Output

5
7
11
101
131
151
181
191
313
353
373
383


问题:数值太大,先判断回文数,再判断素数,依然超时;
于是为了。。。为了缩短时间:
1、将除11以外的偶数位回文数剪掉。据说偶数位的回文数都可以被11整除,显然不是素数,结果出来只是减少了10ms左右,问题显然不是这个。
2、改善判断素数的算法,由2~sqrt(i)依次整除改为,判断
素数出现规律:
当n≧5时,如果n为素数,那么n mod 6 = 1 或 n mod 6 = 5,即n一定出现在6x(x≥1) 两侧。
证明:
当x ≥1时,有如下表示方法:
┈┈  6x,6x+1,6x+2,6x+3,6x+4,6x+5,6(x+1),6(x+1)+1┈┈
不在6x两侧的数为 6x+2 6x+3 6x+4,即2(3x+1),3(2x+1),2(3x+2),它们一定不是素数,所以素数一定出现在6x的两侧。

高效判断一个大于1的数是否为素数:

  1. bool isPrime(int num)  
  2. {  
  3.     if (num == 2 || num == 3)  
  4.     {  
  5.         return true;  
  6.     }  
  7.     if (num % 6 != 1 && num % 6 != 5)  
  8.     {  
  9.         return false;  
  10.     }  
  11.     for (int i = 5; i*i <= num; i += 6)  
  12.     {  
  13.         if (num % i == 0 || num % (i+2) == 0)  
  14.         {  
  15.             return false;  
  16.         }  
  17.     }  
  18.     return true;  



然后发现也只是减少了50ms左右,显然这不是主要问题。
3、将全部结果输出,发现最大素数为9989899<<100000000,所以加判断  if(b>=9989899)        b=9989899;
结果通过了。


代码:
#include <iostream>
#include <stdio.h>

using namespace std;


int main()
{
    int i,j,k,t;
    int bool1,bool2;
    int a,b;
    int p1[15];
    cin>>a>>b;
    if(b>=9989899)
        b=9989899;
    for(i=a;i<=b;i++)
    {
        j=0;k=i;
        while(k>0)
        {
            p1[j]=k%10;
            j++;
            k/=10;
        }
        if(j%2==0 && i!=11)
            continue;
        bool1=1;
        for(t=0;t<j;t++)
        {
            if(p1[t]!=p1[j-1-t])
            {
                bool1=0;
                break;
            }
        }
        if(bool1==0)
            continue;
        bool2=1;
        if(i%6!=1 && i%6!=5)
            continue;
        for(t=5;t*t<=i;t+=6)
        {
            if(i%t==0 || i%(t+2)==0)
            {
                bool2=0;
                break;
            }
        }
        if(bool2==0)
            continue;
        printf("%d",i);
        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值