记录1
#include <bits/stdc++.h>
using namespace std;
bool f(int n){
for(int i=2;i<n;i++){
if(n%i==0) return false;
}
return true;
}
int re(int n){
int m=0,t=0;
while(n){
t=n%10;
m=m*10+t;
n/=10;
}
return m;
}
int main() {
int n,m;
cin>>n>>m;
for(int i=n;i<=m;i++){
if(f(i)&&f(re(i))) cout<<i<<endl;
}
return 0;
}
本题思路
- 判断素数
- 转换数字
判断素数
因为有数据保证
输入 1 行,包含两个正整数 A 和 B。保证 10<A<B<100。
所以可以直接考虑两位数情况
bool f(int n){
for(int i=2;i<n;i++){
if(n%i==0) return false;
}
return true;
}
补充:6k±1优化法判断素数
bool isPrime6k(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) return false;
}
return true;
}
6k±1优化法的数学原理
所有大于3的素数均可以表示为6k±1的形式(其中k为正整数)。这一特性源于数论中对整数模6的分类:
- 任何整数n模6的余数只能是0、1、2、3、4或5。
- 若n ≡ 0、2、4 (mod 6),则n为偶数,大于2时必为合数。
- 若n ≡ 3 (mod 6),则n为3的倍数,大于3时必为合数。
- 仅当n ≡ 1或5 (mod 6)时,n可能是素数(5 ≡ -1 mod 6,故统一表示为6k±1)。
减少检查次数的原因
传统素数检查需试除所有小于√n的整数,而6k±1法通过数学性质排除了以下情况:
- 无需检查偶数(2的倍数)。
- 无需检查3的倍数。
- 仅需检查6k±1形式的数,即每6个数中仅检查2个候选。
例如,检查n=37是否为素数:
- 常规方法需试除2、3、4、5、6(共5次)。
- 6k±1法仅需试除5(=6×1-1)和7(=6×1+1,但7²>37),实际只需检查5(1次)。
实现效率提升
对于大数n,检查次数从O(√n)降低到O(√n/3),因为:
- 原始方法需√n次检查。
- 优化后仅需检查1/3的数(6k±1占全部数的1/3)。
公式化表达为: 检查范围缩减至:k ≤ ⌊√n/6⌋
每次k生成两个候选除数:6k−1和6k+1。
转换数字
int re(int n){
int m=0,t=0;
while(n){
t=n%10;
m=m*10+t;
n/=10;
}
return m;
}
简单的数位分离,%10相当于拿出数的尾巴,/10相当于砍掉数的尾巴
倒过来时候,通过乘10来进行扩大数的位数,然后加上尾巴数