C语言求回文素数

1.问题描述

所谓回文素数指的是,对一个整数n从左向右和从右向左读其数值都相同且n为素数,则称整数为回文素数。

对于偶数位的整数,除了11以外,都不存在回文素数。即所有的4位整数、6位整数、 8位整数…都不存在回文素数。下面列出两位和三位整数中包含的所有回文素数。

两位回文素数:11

三位回文素数:101、131、151、181、191、313、353、373、383、727、757、787、 797、 919、 929

本题要求解的问题是:求出所有不超过1000的回文素数。

问题分析

本题要使用判断素数的方法,并且要解决如何求一个整数的回文数。

采用的方法是穷举法。对1000以内的每一个整数n进行考察,判断n是否为回文数。如果n是回文数,再判断它是否为素数,对于既是回文数也是素数的整数n,就是要求的回文素数,将其打印输出即可。

由于题目要求解的是所有不超过1000的回文素数,因此最后的结果中应该包含两位和三位的回文数。

采用穷举法来构造一个整数并求与其对应的反序数,若整数与其反序数相等,则该整数是回文数。

算法设计

在问题分析中己经确定要采用穷举法逐一考察1000以内的每个整数,因此本题的算法设计可以釆用循环结构来完成。

通过三重循环来遍历所有1000以内的整数。用三个循环变量来构造整数n,同时,这三个循环变量反序便可以构造出n的反序数m。其中,特别要注意的是如果n的个位为0,接下来要做的就是比较m和n的值是否相等,如果相等,则表明整数n是回文数。再来判断n是否是素数,如果n同时也为素数,则n为回文素数,将其打印出来即可。

下面是完整的代码:

#include<stdio.h>
int fun(int n);
int main()
{
    int i, j, k, n, m;
    printf("不超过1000的回文数:\n");
    for(i=0; i<=9; ++i)  /*穷举第一位*/
        for(j=0; j<=9; ++j)  /*穷举第二位*/
            for(k=0; k<=9; ++k)  /*穷举第三位*/
            {
                n=i*100+j*10+k;  /*计算组成的整数*/
                m=k*100+j*10+i;  /*计算对应的反序数*/
                if(i==0 && j==0)  /*处理整数的前两位为0的情况*/
                {
                    m=m/100;
                }
                else if(i==0)  /*处理整数的第一位为0的情况*/
                {
                    m=m/10;
                }
                if(n>10 && n==m && fun(n))  /*若大于10且为回文素数,则输出*/
                {
                    printf("%d\t", n);
                }
            }
    printf("\n");
   
    return 0;
}
/*判断参数n是否为素数*/
int fun(int n)
{
    int i;
    for(i=2; i<(n-1)/2; ++i)
    {
        if(n%i == 0)
            return 0;
    }
    return 1;
}
运行结果:
不超过1000的回文数:
11 101 131 151 181 191 313 353 373 383 727 757 787 797 919 929

转载来自:c语言中文网

2.一亿以内的回文素数

题目分析:
1.多组测试数据,所以先打表。
2.先求质数再判断回文,效率低下;所以先构造回文数,再判断质数。
3.偶数位的回文数都能被11整除,自己证明去。所以,偶数位的回文数除了11都是合数。
4.一个k位数,可以构造出一个奇数位的回文数。比如13,可以构造131;189可以构造18981.所以100000000内的只要从1构造到9999即可。
5.若范围为1000000000,那么明显超出int范围,要用long long。当然此题无此陷阱。
6. 最后按从小到大的顺序输出,优先队列搞定。
#include <iostream>  
#include <cstdio>  
#include <cstring>  
#include <cstdlib>  
#include <queue>  
#include <cmath>  
#include <vector>  
#define MAXN 10000  
#define RST(N)memset(N, 0, sizeof(N))  
using namespace std;  
  
typedef long long LL;  
  
struct cmp  
{  
    bool operator()(const int &a, const int &b)  
    {  
        return a > b;  
    }  
};  
  
priority_queue <int, vector<int>, cmp> pq;  
  
bool is_prime(int x)  
{  
    for(int i=2; i<sqrt(x+0.5); i++) {  
        if(x % i == 0) return false;  
    }  
    return true;  
}  
  
int main()  
{  
    //freopen("data.in", "r", stdin);  
    //freopen("data.out", "w", stdout);  
    while(!pq.empty()) pq.pop();  
    pq.push(11);  
    int sum, tmp;  
    for(int i=2; i<MAXN; i++) {  
        for(sum=i, tmp=i/10; tmp!=0; tmp/=10) {  
            sum = sum*10 + tmp%10;  
        }  
        if(is_prime(sum)) pq.push(sum);  
    }  
    while(!pq.empty()) {  
        cout << pq.top() << endl;  
        pq.pop();  
    }  
    return 0;  
}  
转载来自:http://blog.csdn.net/u011225629/article/details/48109673



  • 22
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值