目录:
【题目描述】
【AC代码】
【回文数和质数】
【作者思路】
【一些闲话】
【题目描述】
因为 151151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151151 是回文质数。
写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)[a,b](5≤a<b≤100,000,000)(一亿)间的所有回文质数。
第一行输入两个正整数 a 和 b。
输出一个回文质数的列表,一行一个。
输入:5 500
输出:
5
7
11
101
131
151
181
191
313
353
373
383
【AC代码】
#include <bits/stdc++.h>
using namespace std;
bool check(int x)//判断该回文数是否为质数
{
for(int i=2;i<=sqrt(x);i++)
{
if(x%i==0)
{
return false;
}
}
return true;
}
int main()
{
int a,b;
cin>>a>>b;
int d1,d2,d3,d4,d5,d6,d7;
int palindrome;
if(a<=10)//产生从0到10的回文数,此时回文数是一位
{
for(int i=2;i<=10;i++)
{
if(i>b)//如果目前产生的回文数大于b,程序结束
{
return 0;
}
if(check(i)&&i>=a)//判断当前回文数是否为质数,并是否满足>=a
{
cout<<i<<endl;//如果满足条件输出并换行
}
}
}
if(a<=100)//产生从11到100的回文数,此时回文数是两位
{
for(int i=11;i<=100;)//原理同上
{
if(i>b)
{
return 0;
}
if(check(i)&&i>=a)
{
cout<<i<<endl;
}
i+=11;//在11到100中,只有11的倍数才是回文数,例如22,33
}
}
if(a<=999)产生从101到999的回文数,此时回文数是三位
{
for(d1=1;d1<=9;d1+=2)//只有奇数才可能是素数,d1作为个位数字必须是奇数,所以+2
{
for(d2=0;d2<=9;d2++)//d2没有奇数要求,所以+1
{
palindrome=100*d1+10*d2+d1;//产生三位回文数的模板
if(palindrome>b)
{
return 0;
}
if(check(palindrome)&&palindrome>=a)
{
cout<<palindrome<<endl;
}
}
}
}
if(a<=9999)//此时输出的回文数是四位
{
for(d1=1;d1<=9;d1+=2)
{
for(d2=0;d2<=9;d2++)
{
palindrome=1000*d1+100*d2+d2*10+d1;//产生四位回文数的模板
if(palindrome>b)
{
return 0;
}
if(check(palindrome)&&palindrome>=a)
{
cout<<palindrome<<endl;
}
}
}
}
if(a<99999)
{
for (d1 = 1; d1 <= 9; d1+=2) //5
{ // 只有奇数才会是素数
for (d2 = 0; d2 <= 9; d2++)
{
for (d3 = 0; d3 <= 9; d3++)
{
palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;
if(palindrome>b)
{
return 0;
}
if(check(palindrome)&&palindrome>=a)
{
cout<<palindrome<<endl;
}
}
}
}
}
if(a<999999)//6
{
for (d1 = 1; d1 <= 9; d1+=2) //5
{ // 只有奇数才会是素数
for (d2 = 0; d2 <= 9; d2++)
{
for (d3 = 0; d3 <= 9; d3++)
{
palindrome = 100000*d1 + 10000*d2 +1000*d3 +100*d3+ 10*d2 + d1;
if(palindrome>b)
{
return 0;
}
if(check(palindrome)&&palindrome>=a)
{
cout<<palindrome<<endl;
}
}
}
}
}
if(a<9999999)//7
{
for (d1 = 1; d1 <= 9; d1+=2) //5
{ // 只有奇数才会是素数
for (d2 = 0; d2 <= 9; d2++)
{
for (d3 = 0; d3 <= 9; d3++)
{
for(d4=0;d4<=9;d4++)
{
palindrome = 1000000*d1 + 100000*d2 +10000*d3 +1000*d4+100*d3+ 10*d2 + d1;
if(palindrome>b)
{
return 0;
}
if(check(palindrome)&&palindrome>=a)
{
cout<<palindrome<<endl;
}
}
}
}
}
}
if(a<99999999)//测试案例数据范围5~1e8,所以到此产生回文数完全够用
{
for (d1 = 1; d1 <= 9; d1+=2) //d1作为头和尾部数字出现
{ // 只有奇数才会是素数
for (d2 = 0; d2 <= 9; d2++)
{
for (d3 = 0; d3 <= 9; d3++)
{
for(d4=0;d4<=9;d4++)
{
palindrome=10000000*d1+1000000*d2+100000*d3+10000*d4+1000*d4+100*d3+10*d2 +
d1;
if(palindrome>b)
{
return 0;
}
if(check(palindrome)&&palindrome>=a)
{
cout<<palindrome<<endl;
}
}
}
}
}
}
return 0;
}
【回文数与质数】
回文数产生模板:
for (d1 = 1; d1 <= 9; d1+=2) { // 只有奇数才会是素数
for (d2 = 0; d2 <= 9; d2++) {
for (d3 = 0; d3 <= 9; d3++) {
palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...)
}
}
质数判断模板:
bool check(int x)//判断该回文数是否为质数,1不是质数
{
for(int i=2;i<=sqrt(x);i++)//
{
if(x%i==0)
{
return false;
}
}
return true;
}
【作者思路】
作者首先想到的就是不停循环a~b并判断是否为回文数或质数,后来根据题目提示又想到可以产生回文数,并判断该数是否为质数。相比于直接循环判断该方法时间复杂度更小,AC只用53ms,而用循环判断AC需要183ms,当然二者本质还是暴力枚举
【一些闲话】
欢迎各位dalao指出错误,提问,博主(bme专业)一定尽力解答