AcWing 3792. 质数问题 java 线性筛法 (小学生都能看懂)

🤠 原题地址

🧐 线性筛法求素数表 O(n)

① 素数只有两个因子,1和本身,但合数就不止了, 而线性筛法核心就是用最小的素因子把合数筛掉

② 例 (p为素数数组) 质数p[z] * i = t1; 怎么保证 质数p[z]  一定是 t1 的最小质因子呢?
  当 i % p[z] = 0时,说明 i = k * p[z], (k为整数), 那么 t2 =  p[z+1] * i = p[z+1] * k * p[z] ,
  由于素数数组 p 是单调递增的,此时 t2 的最小质因子是 p[z] 而不是 p[z+1]
  ->> 当 i % p[z] == 0 时,就可以不用枚举素数数组了,直接 break,避免后边的重复筛选

③ 还是有点蒙? 那就再进一步分析!
  假设 t = p[z] * i , t 被此最小质因子 p[z] 筛掉,那好,反过来想, i 肯定是 t 的除本身外的最大因子了
  怎么保证 i 一定是最大因子呢? 
  只要 i % p[z] = 0 成立就 break 掉, 间接保证了 p[z] <= i 了,哈哈
import java.util.*;

public class Main
{
	static int N = 1010;
	static int primes[] = new int[N], cnt;
	static boolean[] st = new boolean[N];

	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int t = sc.nextInt();
		// N 不减一 就会越界,求的 是 1~N 之间的质数,但下标只有 1~N-1 ;
		get_primes(N - 1);
		while (t-- > 0)
		{
			int n = sc.nextInt();
			int k = sc.nextInt();
			int res = 0;
			for (int i = 2; i <= n; i++)
			{
				if (st[i])// 去掉非素数
					continue;

				for (int j = 1; primes[j] < i; j++)
				{
					if (primes[j] + primes[j - 1] + 1 == i)
					{
						res++;
					}
				}
			}

			if (res >= k)
				System.out.println("YES");
			else
			{
				System.out.println("NO");
			}

		}
	}

	private static void get_primes(int n)
	{
		for (int i = 2; i <= n; i++)
		{
			if (!st[i])
				primes[cnt++] = i;
//			用最小的质因子来筛掉合数
//			当 i 是质数,质数*质数 = 合数
//			当 i 是合数,质数*合数 = 合数
			for (int j = 0; primes[j] <= n / i; j++)// 条件确保 i * p[j] 不会爆 int
			{
				st[primes[j] * i] = true;
				if (i % primes[j] == 0)// 条件成立时,primes[j] 就是 i 的最小质因数
					break; 

			}
		}
	}
 
}

posted @   兑生  阅读(17)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
Live2D
欢迎阅读『AcWing 3792. 质数问题 java 线性筛法 (小学生都能看懂)』
点击右上角即可分享
微信分享提示