P1217 [USACO1.5] 回文质数 Prime Palindromes

发布于:2025-07-14 ⋅ 阅读:(19) ⋅ 点赞:(0)

题目描述

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

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

输入格式

第一行输入两个正整数 a 和 b。

输出格式

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

输入输出样例

输入 #1复制运行

5 500

输出 #1复制运行

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

说明/提示

Hint 1: Generate the palindromes and see if they are prime.

提示 1: 找出所有的回文数再判断它们是不是质数(素数).

Hint 2: Generate palindromes by combining digits properly. You might need more than one of the loops like below.

提示 2: 要产生正确的回文数,你可能需要几个像下面这样的循环。

题目翻译来自NOCOW。

USACO Training Section 1.5

产生长度为 5 的回文数:

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;//(处理回文数...)
         }
     }
 }

 解题思路:

首先在这个范围里找到所有的回文数,再从回文数中判断它是不是质数就可以了。

找到所有的回文数:

1.首先你要能找到一个位数中的所有回文数,例如2位数,范围10~99中的回文数

思路是:回文数,从前看后于从后看前是一样的,所以可以把这个位数砍成一半,例如12321或123321,砍成123,再123*10+3,再(123*10+3)*10+2等等,变回一个回文数,

根据一个位数找其中的所有回文数的代码为:
vector<long long> number_pali(long long h){//h为一个位数
	vector<long long> array;
	long long start=pow(10,(h-1)/2);
	long long end=pow(10,(h+1)/2)-1;
	long long a,b;
	for(long long i=start;i<=end;i++){
		a=i;
		b=i;
		if(h%2)
			b=b/10;
		while(b){
			a=a*10+b%10;
			b/=10;
		}
		array.push_back(a);
	}
	return array;
}

 2.你要能知道这个范围里有多少位数,例如:5~123,有1位数,2位数,3位数;

然后就可以结合1.从一个位数中找到所有的回文数,可以找到这个范围里的所有回文数。

找到一个范围里所有的回文数的代码为:
void pali(long long a,long long b,long long c,long long d){//a,b为这个范围的最小和最大位数,c,d为范围最小数和最大数
	for(long long i=a;i<=b;i++){
		vector<long long> array=number_pali(i);
		for(long long j=0;j<array.size();j++){
			if(isprime(array[j])&&c<=array[j]&&array[j]<=d){
				cout<<array[j]<<endl;
			}
		}
	}
}

 判断质数代码为【6k+1优化算法】:

bool isprime(long long h){//6k+1优化算法
	 if(h<=1)
	     return false;
	 if(h<=3)
	     return true;
	if(h%2==0||h%3==0)
		return false;
	for(long long i=5;i<=sqrt(h);i+=6){
		if(h%i==0||h%(i+2)==0){
			return false;
		}
	}
	return true;
}

总体代码为

#include<bits/stdc++.h>
using namespace std;
long long number(long long h){//看这个数有多少位
	long long a=0;
	while(h){
		h/=10;
		a++;
	}
	return a;
}
bool isprime(long long h){//6k+1优化算法
	 if(h<=1)
	     return false;
	 if(h<=3)
	     return true;
	if(h%2==0||h%3==0)
		return false;
	for(long long i=5;i<=sqrt(h);i+=6){
		if(h%i==0||h%(i+2)==0){
			return false;
		}
	}
	return true;
}
vector<long long> number_pali(long long h){//h为一个位数
	vector<long long> array;
	long long start=pow(10,(h-1)/2);
	long long end=pow(10,(h+1)/2)-1;
	long long a,b;
	for(long long i=start;i<=end;i++){
		a=i;
		b=i;
		if(h%2)
			b=b/10;
		while(b){
			a=a*10+b%10;
			b/=10;
		}
		array.push_back(a);
	}
	return array;
}
void pali(long long a,long long b,long long c,long long d){//a,b为这个范围的最小和最大位数,c,d为范围最小数和最大数
	for(long long i=a;i<=b;i++){
		vector<long long> array=number_pali(i);
		for(long long j=0;j<array.size();j++){
			if(isprime(array[j])&&c<=array[j]&&array[j]<=d){
				cout<<array[j]<<endl;
			}
		}
	}
}
int main(){
	long long a,b,number1,number2;
	cin>>a>>b;
	number1=number(a);
	number2=number(b);
	pali(number1,number2,a,b);
	return 0;
}

 


网站公告

今日签到

点亮在社区的每一天
去签到