洛谷p1009题讲析

一、题目描述 因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。 写一个程序来找出范围 [a,b](5≤a<b≤100,000,000)(一亿)间的所有回文质数。 二、思路展开 首先,我们知道要筛选回文数和质数,

一、题目描述

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

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

二、思路展开

首先,我们知道要筛选回文数和质数,由于回文数只需判断数字是否左右对称,而质数需要遍历寻找因子,显然找到回文数更加容易。

所以我们先筛选出范围内的回文数,再筛选出其中的质数。

在打代码前,有几点性质需要了解。

2.1 回文数

2.1.1 回文数的性质

  • 可以被11整除
  • 不存在偶数位的回文数
  • 一位数都是回文数

2.1.2 如何检索回文数

在处理回文数之前,学习高精度的写法是必须的。

int p = x;    //x为需要存储的数
int pL = 0;    //有几位数
while(p>0){   
	number[pL++] = p%10;    //一位一位赋值
	p/=10;
}

比如我们给x赋值352,那么存到number数组里的效果就是:

number[0]
>>2
number[1]
>>5
number[2]
>>3

没错,反向存入~~

接下来对两边的数字进行检查就好啦:

//pL为数位长度
if(pL%2==0){
	for(;i<=pL/2-1;i++){	//偶数位
		if(number[i]!=number[pL-1-i]){
			return 0;
		}	
	}	
	return 1;
    }
for(;i<=(pL-1)/2-1;i++){    //奇数位
	if(number[i]!=number[pL-1-i]){
		return 0;
	}
}
	return 1;

2.2 质数

2.2.1 质数的性质

  • 不能被1和自身以外的数整除
  • 2是质数

2.2.2 如何检索质数

由于根号x * 根号x = x,所以可以知道所有因子关于x对称。

举个例子,10 = 2 * 5 = 5 * 2 = sqrt(10)*sqrt(10)。所以前乘数只需要扫到sqrt(x)就可以停了。

这样能节省一半的算法~

由于题目将范围设定在[5,100 000 000]之间,所以我们先过滤掉两位以外的偶数位数(四位数、六位数、八位数)。

原因是这类数可以被11整除,不是质数。因此我们在前期就直接筛去它们。

最后对着每个数直接判断三次就行啦

三、完整代码

#include <bits/stdc++.h>
using namespace std;

int min_(int a,int b){
	if(a<b) return a;
	else return b;
}

bool checkLen(int x){//检查位数和奇偶
	if((x>=1000&&x<=9999)||(x>=100000&&x<=999999)){
		return 0;
	}
	return 1;
}	
bool checkMalin(int x){	//检查回文
	int number[10];
	int p = x;
	int pL = 0;
	while(p>0){
		number[pL++] = p%10;
		p/=10;
	}
	int i=0;
	if(pL%2==0){
		for(;i<=pL/2-1;i++){	//偶数位
			if(number[i]!=number[pL-1-i]){
				return 0;
			}	
		}	
		return 1;
	}
	for(;i<=(pL-1)/2-1;i++){
		if(number[i]!=number[pL-1-i]){
			return 0;
		}
	}
	return 1;
	
}
bool checkPrime(int x){	//检查质数
	if(x==2){
		return 1;
	}
	for(int i=2;i<=sqrt(x);i++){
		if(x%i==0){
			return 0;
		}
	}
	return 1;
}
		
		
int main(){
	int min,max;
	scanf("%d %d",&min,&max);
	if(min%2==0){
		min++;	//奇数开始
	}
	max = min_(9999999,max);	//回文质数
	for(int i=min;i<=max;i+=2){	//奇数
		if(!checkLen(i)){
			continue;
		}
		if(!checkMalin(i)){
			continue;
		}
		if(!checkPrime(i)){
			continue;
		}
		printf("%d\n",i);
	}
	return 0;
}

感谢来访与阅读,欢迎各路大佬批评与指点意见

知秋君
上一篇 2024-08-17 15:36
下一篇 2024-08-17 15:02

相关推荐