B3939 绝对素数

记录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. 判断素数
  2. 转换数字

判断素数

因为有数据保证

输入 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来进行扩大数的位数,然后加上尾巴数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值