DAY 13 素数小结 超用心

本次小结要介绍所有有关素数的*知识,题解与模板

这是目前为止写的最用心的一次博客了,耗时3个小时!边学边做题边写。

首先要介绍的是最普通的素数判定!!!!!
先上例题:

试题 算法提高 素数判断

资源限制
时间限制:1.0s 内存限制:512.0MB
编写一函数IsPrime,判断某个大于2的正整数是否为素数。
样例输入:
5
样例输出:
yes
样例输入:
9
样例输出:
no
注意:是素数输出yes,不是素数输出no,其中yes和no均为小写。

核心思路

:素数的概念!即只可被1和自身整除!!!
Ps. 0,1不是素数哦

AC代码:

#include<iostream>
using namespace std;
int isprime(int n)
{
	if (n < 2)
		return 0;
	int i;
	for (i = 2; i < n; i++)
	{
		if (n%i == 0)
			return 0;
		else
			return 1;
	}
}
int main()
{
	int n,k;
	cin >> n;
	k=isprime(n);
	if (k == 1)
		cout << "yes" << endl;
	else
		cout << "no" << endl;
	return 0;
}

该算法运算步骤较多,而且运算较大数字时会超时。



所以接下来要介绍第一种素数筛选方法:

埃筛(Eratosthenes)

用埃筛进行素数筛选可以有效的提升运算速度,核心思路是:寻找第一个素数,之后将此素数所有的整数倍数全部剔除在运算超大数时,运算步骤大大减少。
以下程序是求一千万以内素数的个数的代码:

#include<iostream>
using namespace std;
#define M 10000000
bool flag[M + 1] = {};//初始化,0为质数
int prime[M];//用来存质数
int main()
{
	long long cnt = 0,sum=0;
	for (int i=2;i<M+1;i++)
		if (flag[i]==0)
		{
			prime[cnt] = i;
			cnt++;
			for (int j = 2; j <= M / i; j++)
				flag[i*j] = 1;
		}
	cout << cnt<<endl;
	return 0;
}

不过此筛法还不是最优筛法,因为每次扫过公倍数的时候就会重复一次,入剔除2的倍数6,在剔除3的倍数时,还会再扫一遍


来道例题

试题 算法提高 素数求和

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
  输入一个自然数n,求小于等于n的素数之和
样例输入
2
样例输出
2
数据规模和约定
  测试样例保证 2 <= n <= 2,000,000

本题需要注意它的数据规模,比较大,用最普通的素数判定算法,绝对会超时!(只过了两组,当然可能是因为我比较笨)因此我们可以用埃筛来进行和的运算。

AC代码如下:

#include<iostream>
#include<cstring>
using namespace std;
#define M 2000000
bool flag[M + 1] = {};
typedef long long ll;
int main()
{
	ll n, sum=0,i;
	cin >> n;
	for (i = 2; i <= n; i++)
	{
		if (flag[i]==0)
		{
			sum += i;
			for (int j = 2; j <= n/i; j++)
				flag[i*j] = 1;
		}
	}
	cout << sum << endl;
	return 0;
}


接下来是第二种素数筛法,也就是大名鼎鼎的:

欧拉筛(线性筛)

这是目前为止我了解到的最棒的筛法了,它的时间复杂度仅有O(n).
欧筛就是一个数只用自己最小的质因数筛去
举个例子:筛掉6的时候只需要用到2,而不用3筛,这样就减少了筛选的步骤
实现代码如下:

void euler_sieve(int n)
{
    totPrimes = 0;
    memset(flag, 0, sizeof(flag));//记得加头文件

    for (int i = 2; i <= n; i++) {
        if (!flag[i])
            primes[totPrimes++] = i;
        for (int j = 0; i * primes[j] <= n; j++) {
            flag[i*primes[j]] = true;
            if (i % primes[j] == 0)
                break;
        }
    }
}


之后呢,我找到了几道需要用到质数知识的题目,类似于分解质因数,求完数等,题目即题解如下:

试题 算法提高 8-1因式分解

资源限制
时间限制:10.0s 内存限制:256.0MB
问题描述
  设计算法,用户输入合数,程序输出若个素数的乘积。例如,输入6,输出23。输入20,输出22*5。
样例
  与上面的样例输入对应的输出。
  例:在这里插入图片描述

数据规模和约定
  输入数据中每一个数在int表示范围内。

AC代码:

#include<iostream>
using namespace std;
int main()
{
	int i, n;
	cin >> n;
	for (i = 2; i <= n; i++)
	{
		while (n % i == 0)
		{
			if (i != n)
				cout << i << "*";
			else
				cout << i;
			n /= i;
		}
	}
	return 0;
}

试题 算法训练 完数

资源限制
时间限制:1.0s 内存限制:512.0MB
问题描述
  一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如,6的因子为1、2、3,而6=1+2+3,因此6就是“完数”。又如,28的因子为1、2、4、7、14,而28=1+2+4+7+14,因此28也是“完数”。编写一个程序,判断用户输入的一个数是否为“完数”。
  输入格式:输入只有一行,即一个整数。
  输出格式:输出只有一行,如果该数为完数,输出yes,否则输出no。
  输入输出样例
样例输入
6
样例输出
yes

AC代码:

#include<iostream>
using namespace std;
int main()
{
	int n, i,sum=0;
	cin >> n;
	for (i = 1; i < n; i++)
		if (n%i == 0)
			sum += i;
	if (sum == n)
		cout << "yes" << endl;
	else
		cout << "no" << endl;
	return 0;
}

试题 算法训练 友好数

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
  有两个整数,如果每个整数的约数和(除了它本身以外)等于对方,我们就称这对数是友好的。例如:
  9的约数和有:1+3=4
  4的约数和有:1+2=3
  所以9和4不是友好的。
  220的约数和有:1 2 4 5 10 11 20 22 44 55 110=284
  284的约数和有:1 2 4 71 142=220
  所以220和284是友好的。
  编写程序,判断两个数是否是友好数。
输入格式
  一行,两个整数,由空格分隔
输出格式
  如果是友好数,输出"yes",否则输出"no",注意不包含引号。
样例输入
220 284
样例输出
yes
数据规模和约定
  两个整数都小于10000

AC代码:

#include<iostream>
using namespace std;
int main()
{
	int a, b,sum1=0,sum2=0;
	cin >> a >> b;
	int i;
	for (i = 1; i < a; i++)
	{
		if (a%i == 0)
			sum1 += i;
	}
	for (i = 1; i < b; i++)
	{
		if (b%i == 0)
			sum2+= i;
	}
	if (sum1 == b && sum2 == a)
		cout << "yes" << endl;
	else
		cout << "no" << endl;
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值