20240322每日一题题解

20240322每日一题题解

Problem

输入 n 个不大于 105 的正整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。

第一行输入一个正整数 n,表示整数个数。

第二行输入 n 个正整数 ai,以空格隔开。

输出一行,依次输出 ai 中剩余的质数,以空格隔开。

例如,输入

5
3 4 5 6 7

应当输出

3 5 7

注意数据范围:1n1001ai105

Solution

判断素数最最暴力的办法,就是枚举[2,x1]区间内有没有数字i使得x0(modi)

我们将这一循环判断写成函数,然后对于输入的每个数,调用函数判断其是否为质数。如果是质数,则输出这个数字;如果不是,则跳过。这样就不用把所有数据读取存入数组中了。

#include<iostream>
using namespace std;

bool judge_prime(int x)
{
	if(x==1) return 0;
	for(int i=2;i<x;i++)
	{
		if(x%i==0) return 0;
	}
	return 1;
}

int main()
{
	int n;cin>>n;
	for(int i=1,a;i<=n;i++)
	{
		cin>>a;
		if(judge_prime(a)) cout<<a<<" ";
	}
	return 0;
}

优化

其实我们不需要枚举i[2,x1],只需要枚举[2,x]即可。因为x的因数一定是成对出现的(除了x),并且如果一个因数pix,则定有其对应的因数xpix​。

所以我们可以修改循环条件为i*i<=x

bool judge_prime(int x)
{
	if(x==1) return 0;
	for(int i=2;i*i<=x;i++)
	{
		if(x%i==0) return 0;
	}
	return 1;
}

再优化

可以将105以内的质数都预处理出来,使用到了埃氏筛

#include<iostream>
using namespace std;

bool prime[100010];//1表示不是质数,0表示是质数

int main()
{
	prime[1]=1;//1不是质数
	for(int i=2;i<=100000;i++)
	{
		if(prime[i]==0)//如果i是质数
		{
			for(int j=i*2;j<=100000;j+=i)//那么将i的倍数都打上标记
			{
				prime[j]=1;
			}
		}
	}
	
	
	int n;cin>>n;
	for(int i=1,a;i<=n;i++)
	{
		cin>>a;
		if(prime[a]==0) cout<<a<<" ";
	}
	return 0;
}

当然,在这道题里面,这种做法优势不大。

对于数字更大更多(例如n106,ai108的范围),有兴趣可以了解一下线性筛例题点我

对于快速判断大质数,有兴趣可以去了解Miller–Rabin 素性测试。

参考文献

素数 - OI Wiki

posted @   Vanilla_chan  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
历史上的今天:
2021-03-22 洛谷 P3792 由乃与大母神原型和偶像崇拜
2021-03-22 记一道有趣的交互题 noi.ac #2035歪比巴卜
点击右上角即可分享
微信分享提示