常用数据处理与时间优化(素数筛)

前言

本文是对刷题过程中常常用到的一些数据判断和处理的方法,会不断进行积累与修改,可作为做题参考。

一、判断奇偶数

int func(int n)
{
	if (n % 2 == 0) return 1;
	else return 0;
}

二、筛素数最简单办法

int func(int n)
{
	for(int i=2;i*i<n;i++)
		if (n % i == 0) 
			return 0;
	return 1;
}

注意: 只用判断sqrt(n)以前的数据就可以了,一个因子一定小于等于sqrt(n),另一个一定大于等于sqrt(n)。而为了避免浮点数,就是用i的平方进行判断。时间复杂度为O(sqrt(n))

三、埃氏筛

首先需要定义一个储存是否为素数的数组

bool Prime[20000];

然后初始化:而且假设2-n都是素数(1不是,直接排除)

for(int i=2;i<=n;i++)
Prime[i]=true;

最后遍历数组,这里注意,如果说一个数是素数那么它的倍数一定不是素数。时间复杂度O(n*log(n))

void getPrime(int n)
{
	for(int i=2;i<=n;i++)
		Prime[i]=true;
	for(int i=2;i<=n;i++)
		if(Prime[i])
			for(int j=i;i*j<=n;j++)
				Prime[i*j]=false;
}	

四、欧拉筛

这个相当于是对埃氏筛的进一步优化,避免重复数据进行多次判断。时间复杂度为O(n)
首先定义一个保存素数的数组

int prime[20000];

然后定义一个int类型的变量记录素数数组内个数

int sum=0;

还要定义一个用来标记访问过的数据的数组

bool visit[20000];

整个判断过程代码如下

void getPrime(int n)
{
	for (int i = 2; i <= n; i++) 
		if (visit[i] == false)
			prime[++sum] = i;
	for (int j = 1; j <= sum && i * prime[j] <= n; j++) {
		visit[i * prime[j]] = true;
		if (i % prime[j] == 0)break;
	}
}

五、输入优化之快读

输入速度: 快读>scanf>cin
scanf是已经给出了数据类型,而cin没有给出,所以编译器在输入过程中还需要进行数据类型的判断再进行输入。
模板代码如下:

long long read()
{
	long long ans = 0;
	char last = ' ', ch = getchar();//储存正负号的last
	while (ch < '0' || ch>'9')//如果不是数字类型就直接读入
	{
		last = ch;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9')//是数字类型就读完连续数字为止
	{
		ans = (ans << 3) + (ans << 1);//位运算
		ans += ch - '0';
		ch = getchar();
	}
	return last == '-' ? -ans : ans;//三目运算符
}

位运算比乘法快
三目运算符比if快
具体使用方法:

long long a=read();

总结

本文对常用的知识点进行了总结,后续会有更多的知识点进行补充。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值