您的位置:首页 > 其它

YTU.1419: 1.5.2 Prime Palindromes 回文质数

2017-10-17 12:42 351 查看


1419: 1.5.2 Prime Palindromes 回文质数

时间限制: 1 Sec  内存限制: 64 MB
提交: 99  解决: 20

[提交][状态][讨论版]


题目描述

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


输入

第 1 行: 二个整数 a 和 b


输出

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


样例输入

5 500


样例输出

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


思路:题目说要找的既是质数又是回文数的数字,并把它输出。

那么分别写两个函数来判断是否是质数和是否是回文数即可。
然后从给定范围内进行遍历,若为质数,判断是否为回文数,若是,则输出当前的数。
速度敲代码并运行,没问题 ,然后兴高采烈的去提交。。。
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
int prime(int n)
{
int k,i;
if(n==1)
return 0;
if(n==2)
return 1;
k=sqrt(n);
for(i=2;i<=k;i++)
if(n%i==0)
return 0;
if(i==k+1)
return 1;
}
bool palindrome(int n)
{
char t[10];
sprintf(t,"%d",n);
int i,j;
j=strlen(t);
for(i=0;i<j/2;i++)
if(t[i]!=t[j-i-1])
return false;
return true;
}
int main()
{
int n1,n2;
scanf("%d %d",&n1,&n2);
int i;
for(i=n1;i<=n2;i++)
{
if(prime(i))
{
if(palindrome(i))
printf("%d\n",i);
}
}
return 0;
}




然后仔细一想,这种筛选法判断素数加上遍历那么多的数,复杂度必然是很大的。
那么,换思路:先找到所有的回文数,然后再判断它是不是素数即可。

关键如何按照从小到大的顺序生成回文数呢?

    设生成位数为l的回文数,若l是奇数,那么从小到大枚举(l+1)/2位的数,然后复制翻转生成一个回文数;若l是偶数,那么从小到大枚举l/2位的数,然后复制翻转生成一个回文数。上诉两个过程交替进行就可以从小到大生成回文数了。

同样我们也要注意剪枝:

1、很有效的优化:任意偶数长度的回文数都不可能为质数(除了11),因为它能被11整除,而11恰好只有自身和1两个因子。除2外,所有偶数均不可能是质数。

2、还有一个优化:2位以上的数,尾数为5必不是质数。

    (生成回文数时可以用string[10]来记录,因为可以用insert(string,string,longint)函数,所以比较简便。 生成回文数时对于第一位,可以用case语句,对应1,3,7,9,另外的位就从0到9,直接转为字符,字符加起来再转为数字就行了。)
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>

using namespace std;

int palindrome[1000000];

int isprime(int x){          //判断是否是素数
int i,temp=sqrt(x);
for (i=2;i<=temp;i++)
{   if(x%i==0)
return 0;
}
return 1;
}
int main()
{
int a,b;
scanf("%d %d",&a,&b);
int i=0,d1,d2,d3,d4;
//1位
for (d1 = 2; d1 <= 9; d1+=1)
palindrome[i++] = d1;
//2位
palindrome[i++] = 11;
//3位
for (d1 = 1; d1 <= 9; d1+=2)
for (d2 = 0; d2 <= 9; d2++) {
palindrome[i++] = 100*d1 +10*d2+ d1;
}
//5位
for (d1 = 1; d1 <= 9; d1+=2) {
for (d2 = 0; d2 <= 9; d2++) {
for (d3 = 0; d3 <= 9; d3++) {
palindrome[i++] = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;
}
}
}
//7位
for (d1 = 1; d1 <= 9; d1+=2) {
for (d2 = 0; d2 <= 9; d2++) {
for (d3 = 0; d3 <= 9; d3++) {
for (d4 = 0; d4 <= 9; d4++){
palindrome[i++] = 1000000*d1+100000*d2 + 10000*d3 + 1000*d4 + 100*d3+ 10*d2 + d1;
}
}
}
}

int len;
len=i-1;
for(i=0;i<len&&palindrome[i]<=b;i++){
if (isprime(palindrome[i]) && palindrome[i]>=a){
cout<<palindrome[i]<<endl;
}
}
return 0;
}
代码参考一位大佬博客:USACO:1.5.2 Prime Palindromes 回文质数 点击打开链接
                                     http://blog.csdn.net/finded/article/details/39449349
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: