1.5.3 查找回文质数

题目描述:

http://ace.delos.com/usacoprob2?a=natOyh2BvAP&S=pprime

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

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

 

其实这是水题一道,之所以想总结一下,是想揭露一下自己丑陋的实现代码。

这道题目其实是让找[a,b]区间段的回文质数,比如151,就是一个回文质数。但是b的可取值给的很大,高达1000 000 000,所以不能直接一个一个的去测试,因为从1一直循环到1000 000 000 一定会超时的,所以就得去构造,也就是说,自己构造出指定区间的回文数,然后在检测其是否为质数。

如果去构造的话,比如构造12344321这样的额回文数,就是1*10000001+2*1000010+3*100100+4*11000 = 12344321.。

在代码实现上,可以发现,长度不同的回文数,其具体实现代码不一样。。。想了半天也想不到能揉和到一起的实现代码,没办法,就写了九个子函数,然后用函数指针数组实现的,代码如下,其形极其丑陋无比。尤其是做完后看了标准答案之后,更加得吸取教训。

标准答案的精妙之处在于,他在构造回文数的时候,是先在数字区间便利,然后转成字符串,然后对称构造回文数,然后再将字符串转化为数。其中两个库子函数,我平时用的很少,再次记录一下:

将int转为char *类型的函数:sprintf(buf, "%d", i);

将char*转化为int 类型的函数为: n = atol(buf);

我的代码如下:

#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

int a,b;
int len(int x);
bool isPrime(int x);
bool isIn(int x);

void gen1();void gen2();void gen3();void gen4();void gen5();
void gen6();void gen7();void gen8();void gen9();
void (*gen[10])() = {gen1,gen1,gen2,gen3,gen4,gen5,gen6,gen7,gen8,gen9};

vector<int>results;

ifstream infile;
ofstream outfile;

int main(){
    infile.open("pprime.in");
    outfile.open("pprime.out");

    //cin>>a>>b;
    infile>>a>>b;
    int lenA = len(a);
    int lenB = len(b);

    for(int i=lenA;i<=lenB;i++)
        (*gen[i])();

    for(int i=0;i<results.size();i++)
        //cout<<results[i]<<endl;
        outfile<<results[i]<<endl;
    
    return 0;
}

int len(int x){
    int re = 0;
    while(x){
        re++;
        x/=10;
    }
    return re;
}

bool isPrime(int x){
    for(int i=2;i*i<=x;i++)
        if(x%i == 0)
            return false;
    return true;
}
bool isIn(int x){
    return ((x>=a)&&(x<=b));
}
void dealRes(int temp){
    if(isIn(temp) && isPrime(temp))
            results.push_back(temp);
}
void gen1(){
    if(isIn(5))
        results.push_back(5);
    if(isIn(7))
        results.push_back(7);
}

void gen2(){
    int temp;
    for(int d1=1;d1<=9;d1+=2){
        temp = d1*11;
        dealRes(temp);
    }
}
void gen3(){
    int temp;
    for(int d1=1;d1<=9;d1+=2)
        for(int d2=0;d2<=9;d2++){
            temp = d1*101+d2*10;
            dealRes(temp);
        }
}
void gen4(){
    int temp;
    for(int d1=1;d1<=9;d1+=2)
        for(int d2=0;d2<=9;d2++){
            temp = d1*1001+d2*110;
            dealRes(temp);
        }
}
void gen5(){
    int temp;
    for(int d1=1;d1<=9;d1+=2)
        for(int d2=0;d2<=9;d2++)
            for(int d3=0;d3<=9;d3++)
            {
                temp = d1*10001+d2*1010+d3*100;
                dealRes(temp);
            }
}
void gen6(){
    int temp;
    for(int d1=1;d1<=9;d1+=2)
        for(int d2=0;d2<=9;d2++)
            for(int d3=0;d3<=9;d3++)
            {
                temp = d1*100001+d2*10010+d3*1100;
                dealRes(temp);
            }
}
void gen7(){
    int temp;
    for(int d1=1;d1<=9;d1+=2)
        for(int d2=0;d2<=9;d2++)
            for(int d3=0;d3<=9;d3++)
                for(int d4=0;d4<=9;d4++)
            {
                temp = d1*1000001+d2*100010+d3*10100+d4*1000;
                dealRes(temp);
            }
}
void gen8(){
    int temp;
    for(int d1=1;d1<=9;d1+=2)
        for(int d2=0;d2<=9;d2++)
            for(int d3=0;d3<=9;d3++)
                for(int d4=0;d4<=9;d4++)
            {
                temp = d1*10000001+d2*1000010+d3*100100+d4*11000;
                dealRes(temp);
            }
}
void gen9(){
    int temp;
    for(int d1=1;d1<=9;d1+=2)
        for(int d2=0;d2<=9;d2++)
            for(int d3=0;d3<=9;d3++)
                for(int d4=0;d4<=9;d4++)
                    for(int d5=0;d5<=9;d5++)
            {
                temp = d1*100000001+d2*10000010+d3*1000100+d4*101000+d5*10000;
                dealRes(temp);
            }
}

 

 

官方代码:

#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

FILE *fout;
long a, b;

int
isprime(long n)
{
    long i;

    if(n == 2)
    return 1;

    if(n%2 == 0)
    return 0;

    for(i=3; i*i <= n; i+=2)
    if(n%i == 0)
        return 0;

    return 1;
}

void
gen(int i, int isodd)
{
    char buf[30];
    char *p, *q;
    long n;

    sprintf(buf, "%d", i);

    p = buf+strlen(buf);
    q = p - isodd;

    while(q > buf)
    *p++ = *--q;
    *p = '\0';

    n = atol(buf);
    if(a <= n && n <= b && isprime(n))
    fprintf(fout, "%ld\n", n);
}

void
genoddeven(int lo, int hi)
{
    int i;

    for(i=lo; i<=hi; i++)
        gen(i, 1);

    for(i=lo; i<=hi; i++)
        gen(i, 0);
}

void
generate(void)
{
    genoddeven(1, 9);
    genoddeven(10, 99);
    genoddeven(100, 999);
    genoddeven(1000, 9999);
}

void
main(void)
{
    FILE *fin;

    fin = fopen("pprime.in", "r");
    fout = fopen("pprime.out", "w");
    assert(fin != NULL && fout != NULL);

    fscanf(fin, "%ld %ld", &a, &b);

    generate();
    exit (0);
}

*/

 

转载于:https://www.cnblogs.com/liushang0419/archive/2012/06/05/2536648.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值