保研考研机试攻略:第三章——数学(2)

🍦🍦🍦感谢大家对该专栏的支持,我会继续努力学习更新的,期待大家与我共同进步,我们一起拿捏机试~~~

目录

[🧊🧊🧊3.5 素数判定](#🧊🧊🧊3.5 素数判定)

[🥥例题:DreamJudge 1013](#🥥例题:DreamJudge 1013)

🥥练习题目:

[DreamJudge 1355 素数判定 - 哈尔滨工业大学](#DreamJudge 1355 素数判定 - 哈尔滨工业大学)

[🧊🧊🧊3.6 素数筛选(🌷记模板)](#🧊🧊🧊3.6 素数筛选(🌷记模板))

[🥥例题:DreamJudge 1102](#🥥例题:DreamJudge 1102)

🥥练习题目:

[DreamJudge 1375 素数](#DreamJudge 1375 素数)

[🧊🧊🧊3.7 分解素因数](#🧊🧊🧊3.7 分解素因数)

[🥥例题:DreamJudge 1156](#🥥例题:DreamJudge 1156)

🥥练习题目:

[DreamJudge 1284 整除问题 🍰](#DreamJudge 1284 整除问题 🍰)

[DreamJudge 1464 最大素因子](#DreamJudge 1464 最大素因子)


🧊🧊🧊3.5 素数判定

先说什么是素数?素数就是其因子只有1和本身

那么如何判断一个数x是不是素数呢?我们可以根据素数的定义从2到小于这个数x的每个数去判断当前数是否为x的因子,也就是说,如果x有除了1和本身以外的因子,那他就不是素数。

一般情况下,我们没有必要判断这么多个数,只用判断到sqrt(x)就停止了。这是因为,如果比 sqrt(x)大的数是其因子的话,就必然存在一个比sqrt(x)小的数是其因子。

🥥例题:DreamJudge 1013

首先判断输入的 n 是不是一个素数,如果是的话就直接输出。如果不是的话,从 n+1 开始,对每个数去判断它是不是一个素数,直到找到一个素数的时候终止。

cpp 复制代码
#include <stdio.h>
#include <math.h>
int main() {
    int n;
    scanf("%d", &n);
    if (n == 1) n++;//1 不是素数
    for (int i = n; ; i++) {
        int flag = 0;
        for (int j = 2; j <= sqrt(i); j++) {
            if (i % j == 0) {//如果找到了约数
                flag = 1;//说明不是素数
                break;
            }
        }
        if (flag == 0) {
            printf("%d\n", i);
            break;
        }
    }
    return 0;
}

🥥练习题目:

DreamJudge 1355 素数判定 - 哈尔滨工业大学

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
bool sushu(long long x)
{
	if(x==0||x==1||x<0) return false;
	for(long long i=2;i<x;i++) 
	{
		if(x%i==0) return false;
	}
	return true;
}
int main()
{
	long long n;
	while(cin>>n)
	{
		if(sushu(n)) cout<<"yes"<<endl;
		else cout<<"no"<<endl;
	}
	return 0;
}

🧊🧊🧊3.6 素数筛选(🌷记模板)

有时,题目要求我们筛选出一段区间内的素数,我们就需要掌握一种素数筛选的方法。

如果用上一节素数判定的方法去判定每一个数是不是素数的话,复杂度是 O(n*sqrt(n)),大概只能处理到 1e4 以内的数,如果题目要求的范围大,我们就需要一种更为高效的筛选法。

掌握下面这一种线性复杂度的筛选方法就足够我们应对任何情况:

cpp 复制代码
// 线性素数筛选 prime[0]存的是素数的个数
const int maxn = 1e6 + 5;
int prime[maxn]={0};
void getPrime() {
    for (int i = 2; i <= maxn; i++) {
        if (!prime[i]) prime[++prime[0]] = i;
        for (int j = 1; j <= prime[0] && prime[j] * i <= maxn; j++) {
            prime[prime[j] * i] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}

🥥例题:DreamJudge 1102

这道题的数据范围不大,可以用挨个暴力判断的方法解决。我们假设这道题的数据范围很大,使用素数筛选的方法来解决这个问题。

🥥练习题目:

DreamJudge 1375 素数

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
bool prime(int x)
{
	if(x==1||x==0||x<0) return false;
	for(int i=2;i<x;i++)
	{
		if(x%i==0) return false;
	}
	return true;
}

int main()
{
	int n,flag=0;
	while(cin>>n)
	{
		flag=0;
		for(int i=2;i<n;i++)
		{
			if(prime(i))
			{
				if(i%10==1) 
				{
					cout<<i<<" ";
					flag=1;
				}
			}
		}
		if(flag==0) cout<<-1;
		cout<<endl;
	}
	return 0;
}

🧊🧊🧊3.7 分解素因数

对于任意一个大于1的整数,我们都可以把它分解成多个质因子相乘的形式。

🥥例题:DreamJudge 1156

这道题目,我们可以用上一节学的素数筛选,先将所有的素数筛选出来。然后再不断的分解素数,直到将数分解到 1 为止。由于我们的素数筛选只能到 1000000,对于更大的素因子我们可以不继续分解,因为不会存在两个大于 1000000 的素因子,如果存在,那么这个数的范围一定大于题目所给的范围 10^9。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
// 线性素数筛选 prime[0]存的是素数的个数
const int maxn = 1000000 + 5;
int prime[maxn];
void getPrime() {
    memset(prime, 0, sizeof(prime));
    for (int i = 2; i <= maxn; i++) {
        if (!prime[i]) prime[++prime[0]] = i;
        for (int j = 1; j <= prime[0] && prime[j] * i <= maxn; j++) {
            prime[prime[j] * i] = 1;
            if (i % prime[j] == 0) break;
        }
    }
}
int main() {
    getPrime();//先进行素数筛选预处理
    int n;
    while (scanf("%d", &n) != EOF) {
        int ans = 0;
        for (int i = 1; i <= prime[0]; i++) {
            while (n % prime[i] == 0) {//while就是为了解决重复因子的情况
                n /= prime[i];
                ans++;
            }
        }
        if (n > 1) ans++;
        printf("%d\n", ans);
    }
    return 0;
}

🥥练习题目:

DreamJudge 1284 整除问题 🍰

cpp 复制代码
//题解摘自N诺评论区用户:可以吖
#include<bits/stdc++.h>
using namespace std;
//getPrime就是统计质因子个数的。
void getPrime(vector<int>& factors, int n){
	for(int i=2; i*i<=n; i++){
		while(n % i == 0){
			factors[i]++;
		   //相当于用数组计数,因为题中范围不大,所以可以直接开辟一个1000的数组。
		   //并不是所有位置都用,只有成为n以及后面n--的质因子的位置才用。确实是稍微浪费了一些空间。
			n /= i;
			//这一步就是为了知道该数字有多少了等于i的质因子。比如单独考虑,12=2*2*3,里面有两个2,一个3。
			//则这一步以后factors[2]==2,factors[3]==1。
			if(n <= 1) return;
		}
	}
	if(n > 1) factors[n]++;
	//自身是一个。
}

int main()
{
	int n,a;
	while(cin>>n>>a)
	{
		vector<int> factor_a(1000), factor_n(1000);
		getPrime(factor_a,a);
		for(int i=2;i<=n;i++)
			getPrime(factor_n,i);//在i的质因子统计完以后,factor的已经存了个数,后续也是在这个基础上加
		int k=1000;
		for(int i=2;i<=a;i++)//为什么小于a,上述文字已经说明
		{
			if(factor_a[i])
				k=min(k,factor_n[i]/factor_a[i]);//注意前文定义k为int型。
		}
		cout<<k<<endl;
	}
	return 0;
}

DreamJudge 1464 最大素因子

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
bool isprime(int x)
{
	if(x==1||x==0||x<0) return false;
	for(int i=2;i<=sqrt(x);i++)
	{
		if(x%i==0) return false;
	}
	return true;
}
int main()
{
	int n;
	while(cin>>n)
	{
		string s;
		for(int i=0;i<n;i++)
		{
			cin>>s;
			string cur="";
			for(int j=0;j<s.size();j++)
			{
				if(s[j]>='0'&&s[j]<='9') cur+=s[j];
			}
			int num=0;
			for(int j=0;j<cur.size();j++) num=num*10+(cur[j]-'0');
			//cout<<cur<<" "<<num<<endl;//
			if(cur.size()==0||num==0) 
			{
				//cout<<"yes3"<<endl;//
				cout<<0<<endl;
				continue;
			}
			if(isprime(num)) 
			{
				//cout<<"yes"<<endl;//
				cout<<num<<endl;
				continue;
			}
			//cout<<num<<endl;//
			for(int j=num-1;j>=2;j--) 
			{
				if(num%j==0)
				{
					//cout<<j<<" yes2"<<endl;//
					cout<<j<<endl;
					break;
				}
			}
				
		}
	}
	return 0;
}

创作不易,点个赞吧~点赞收藏不迷路,感兴趣的宝子们欢迎关注该专栏~

勤奋努力的宝子们,学习辛苦了!🌷🌷🌷休息下,我们下部分再见👋( •̀ ω •́ )✧~

相关推荐
Lenyiin1 分钟前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长4 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己6 分钟前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan8 分钟前
C语言:数组转换指针的时机
c语言·开发语言·算法
繁依Fanyi21 分钟前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
烦躁的大鼻嘎37 分钟前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode
IU宝40 分钟前
C/C++内存管理
java·c语言·c++
熙曦Sakura41 分钟前
完全竞争市场
笔记
fhvyxyci41 分钟前
【C++之STL】摸清 string 的模拟实现(下)
开发语言·c++·string
C++忠实粉丝1 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法