蓝桥杯AcWing学习笔记 8-1数论的学习(上)

蓝桥杯

我的AcWing

题目及图片来自蓝桥杯C++ AB组辅导课

数论(上)

蓝桥杯省赛中考的数论不是很多,这里讲几个蓝桥杯常考的知识点。

欧几里得算法——辗转相除法

image-20220304182558152

欧几里得算法代码:

import java.util.Scanner ;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int a = sc.nextInt(), b = sc.nextInt();System.out.println(gcd(a, b));}private static int gcd(int a, int b) {return b != 0 ? gcd(b, a % b) : a;}
}

算术基本定理

就是因式分解的定理,所有的整数都可以唯一分解成若干个质因子乘积的形式:

N = P 1 α 1 × P 2 α 2 × . . . × P k α k N=P_{1}^{α_{1}}×P_{2}^{α_{2}}×...×P_{k}^{α_{k}} N=P1α1×P2α2×...×Pkαk,其中 P i P_{i} Pi 是质数,每一个 α i ≥ 0 α_{i} \geq0 αi0

image-20220304195609211

筛法求素数——线性筛法(欧拉筛法)

O ( N ) O(N) O(N)的时间复杂度内,求出来1 ~ n中所有的质数,以及每一个数的最小质因子。

import java.util.Scanner ;public class Main {static final int N = 1000010;static int[] primes = new int[N]; // 存所有的质数static int cnt; // 存质数的个数static boolean[] st = new boolean[N]; // 当前数有没有被筛过 0没有被筛过 1表示筛过public static void main(String[] args) {get_primes(100000);for (int i = 0; i < 20; i++) System.out.println(primes[i]); // 输出100000的前20个质数}private static void get_primes(int n) {for (int i = 2; i <= n; i++) {if (!st[i]) primes[cnt++] = i;for (int j = 0; primes[j] * i <= n; j++) {/*因为prime中素数是递增的,所以如果i%prime[j]!=0代表i的最小质因数还没有找到,即i的最小质因数大于prime[j]也就是说prime[j]就是i*prime[j]的最小质因数,于是i*prime[j]被它的最小质因数筛掉了*/st[primes[j] * i] = true; // 把质数的i倍筛掉/*如果当i%prime[j]==0时,代表i的最小质因数是prime[j],那么i*prime[j+k](k>0)这个合数的最小质因数就不是prime[j+k]而是prime[j]了所以i*prime[j+k]应该被prime[j]筛掉,而不是后续的prime[j+k],于是在此时break*/if (i % primes[j] == 0) break; // 通过最小质因子来筛}}}
}

注释中的两段解释参考博客 线性筛(欧拉筛)——算法解析

① 筛掉的一定是合数,且一定是用其最小质因子筛的

② 合数一定会被筛掉

image-20220305185612283

这样我们就可以把所有质数找出来,而且每个和数只会被最小质因子筛,所以每个和数只会被筛一次,所以整个算法的时间复杂度为 O ( N ) O(N) O(N)

例题

AcWing 1295. X的因子链

算术基本定理

线性筛法

题意有点绕,通俗来讲就是给我们任意一个正整数 X X X,我们可以求一下 X X X所有的约数: d 1 , d 2 . . . d k d_{1},d_{2}...d_{k} d1,d2...dk,然后我们要从中挑出来一些严格单调递增的数,使得每一项都是它前一项的倍数: a 1 < a 2 < . . . < a t a_{1}<a_{2}<...<a_{t} a1<a2<...<at ( a i ∣ a i + 1 ) (a_{i}|a_{i+1}) (aiai+1),然后问我们可以挑出来的序列的最大长度是多少,以及有多少个满足条件的单调递增的序列?

每一项必然满足: a i + 1 = a i ⋅ P ( P 是倍数且 > 1 ) a_{i+1} = a_{i}·P(P是倍数 且>1) ai+1=aiP(P是倍数且>1),每一个后一项都等于前一项乘上一个倍数,那么我们要想让整个序列最长的话,要尽可能让倍数最小,最小只能小到质数,因为小到质数就不能再分了,因此就可以用我们上边的算术基本定理了,假设 X X X分解质因数的结果: X = P 1 α 1 × P 2 α 2 × . . . × P k α k X=P_{1}^{α_{1}}×P_{2}^{α_{2}}×...×P_{k}^{α_{k}} X=P1α1×P2α2×...×Pkαk,我们可以发现一共有 α 1 + α 2 + . . . + α k α_{1}+α_{2}+...+α_{k} α1+α2+...+αk 个质因子,因此我们每一次后一项要比前一项至少要多一个倍数,每一次的倍数必然是一个质数,必然是在 X X X当中的某一个质因子,所以序列的最大长度就是 α 1 + α 2 + . . . + α k α_{1}+α_{2}+...+α_{k} α1+α2+...+αk

那么如何求这样序列的个数呢?先做一个映射,我们不存数的本身,我们存数的增量,原序列是 a 1 , a 2 . . . a t a_{1},a_{2}...a_{t} a1,a2...at,映射的序列是: a 1 a_{1} a1, a 2 a 1 a_{2}\over a_{1} a1a2, a 3 a 2 a_{3}\over a_{2} a2a3 . . . ... ... a t a t − 1 a_{t}\over a_{t-1} at1at,这两个序列是一一对应的,给我们第一个序列就可以求第二个序列,在第二个序列中每一个数都是 X X X的质因子,因此序列个数就是 X X X所有质因子的排列数。

image-20220305145729674

排列数公式: ( α 1 + α 2 + . . . + α k ) ! α 1 ! ⋅ α 2 ! ⋅ . . . ⋅ α k ! (α_{1}+α_{2}+...+α_{k})! \over α_{1}!·α_{2}!·...·α_{k}! α1!α2!...αk!(α1+α2+...+αk)!,也被称为多重集合的排列数问题,这样就避免了重复情况。

我们分解质因数就用线性筛法来解。

import java.util.Scanner ;public class Main {static final int N = (1 << 20) + 10;static int[] primes = new int[N]; // 存所有的质数static int cnt; // 存质数的个数static int[] minp = new int[N]; // 存最小质因子static boolean[] st = new boolean[N]; // 当前数有没有被筛过public static void main(String[] args) {Scanner sc = new Scanner(System.in);get_primes(N - 1);int[] fact = new int[30]; // 记录因子int[] sum = new int[N]; // 存因子个数while (sc.hasNext()) {int x = sc.nextInt();int k = 0, total = 0;while (x > 1) {int p = minp[x];fact[k] = p;sum[k] = 0;while (x % p == 0) { // 分解质因数x /= p;sum[k]++;total++;}k++;}long res = 1;for (int i = 1; i <= total; i++) res *= i; // 求total的阶乘for (int i = 0; i < k; i++) { // 多重集合的排列数for (int j = 1; j <= sum[i]; j++) {res /= j;}}System.out.println(total + " " + res);}}private static void get_primes(int n) {for (int i = 2; i <= n; i++) {if (!st[i]) {minp[i] = i; // 因为i是质数 最小质因子就是它本身primes[cnt++] = i;}for (int j = 0; primes[j] * i <= n; j++) {int t = primes[j] * i;st[t] = true;minp[t] = primes[j];st[primes[j] * i] = true;if (i % primes[j] == 0) break;}}}
}

第十届2019年蓝桥杯真题

AcWing 1246. 等差数列

C++B组第8题

最大公约数

欧几里得算法

在等差数列中,每一项与第一项的差一定是公差d的倍数,但是题中的等差数列有一部分未连续,所以我们要找到除了第一项,其余的每一项和第一项的差的最大公约数dd就是整个数列公差的最大值。

image-20220304185548071

求项数公式: a 末 − a 首 d a_{末}-a_{首} \over d daa + 1 + 1 +1

时间复杂度 O ( N l o g N ) O(NlogN) O(NlogN)

import java.util.Scanner;
import java.util.Arrays;public class Main {static final int N = 100010;static int[] a = new int[N];public static void main(String[] args) {Scanner sc = new Scanner(System.in);int n = sc.nextInt();for (int i = 0; i < n; i++) a[i] = sc.nextInt();Arrays.sort(a, 0, n);int d = 0;for (int i = 1; i < n; i++) d = gcd(d, a[i] - a[0]); // 求最大公约数if (d == 0) System.out.print(n); // 表示所有项都相同else System.out.print((a[n - 1] - a[0]) / d + 1); // 求项数公式}private static int gcd(int a, int b) {return b != 0 ? gcd(b, a % b) : a;}
}

第七届2016年蓝桥杯真题

AcWing 1223. 最大比例

C++B组第10题

最大公约数

辗转相减法

M M M个奖金构成了一个等比数列,奖金是正整数,但是比值有可能是分数;从这些等比数列挑出一部分数字,通过选出来的这些数来推断原来等比数列的比值的最大可能值是多少。

image-20220307182650365

这题太难了,没肝动。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/345693.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云服务器十大服务商——云服务器哪家好用

云服务器哪家便宜&#xff1f;2024最新整理你要的都在这&#xff01;头部云厂商阿里云、腾讯云、华为云、京东云、UCloud等都在降价&#xff0c;阿腾云atengyun.com分享2024年云服务器租用价格给你惊喜&#xff01; 便宜云服务器阿里云腾讯云华为云 2024年便宜云服务器汇总&…

6.2 声音编辑工具GoldWave5简介(6)

3&#xff0e;选择【选项】|【控制器属性】命名或单击“控制器”面板上的“设置控制器属性”按钮&#xff0c;打开“控制器属性”对话框&#xff0c;将“音量”选项卡中的“麦克风”选项打上勾&#xff0c;使GoldWave只能录制来自麦克风的声音。如果要录制电脑内部的声音&#…

RTMP 视频数据封装

RTMP 协议 与HTTP(超文本传输协议)同样是一个基于TCP的Real Time Messaging Protocol(实时消息传输协议)。由Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输开发的一种开放协议 。在国内被广泛的应用于直 播领域。HTTP默认端口为80&#xff0c;RTMP则为1935…

第8章-第6节-Java中字符流的缓冲流

1、在说正题之前&#xff0c;先说一个小细节&#xff0c;不管是字节流还是字符流都要注意这个细节&#xff0c;具体看这篇博文&#xff1a;关于Java的IO流里面的方法read()的小细节 2、字符流的缓冲流&#xff1a; 1&#xff09;、BufferedWriter 方法名说明void newLine()写…

专业课145+合肥工业大学833信号分析与处理考研经验合工大电子信息通信

今年专业课145也是考研科目中最满意的一门&#xff0c;其他基本相对平平&#xff0c;所以这里我总结一下自己的专业课合肥工业大学833信号分析与处理的复习经验。 我所用的教材是郑君里的《信号与系统》&#xff08;第三版&#xff09;和高西全、丁玉美的《数字信号处理》&…

安装rlwrap库出现问题

背景&#xff1a;oracle的sqlplus还是那么难用&#xff0c;不知道为什么不打包解决这个问题&#xff0c;留给用户&#xff0c;内核硬&#xff0c;就是猖狂。废话不多说。下载解压rlwrap-0.46.1.tar.gz;进入/tmp/database/rlwrap-0.46.1源码包&#xff0c;./configure checki…

Apache Doris (六十三): Spark Doris Connector - (3)-配置型及列映射关系

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录 1. Spark 操作Doris配置项

数据结构学习之顺序栈应用的案例(有效的括号)

实例要求&#xff1a; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效&#xff1b; 有效字符串需满足的条件&#xff1a; 1、左括号必须用相同类型的右括号闭合&#xff1b; 2、左括号必须…

C++力扣题目98--验证二叉搜索树

给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a; 输入…

AI Table应用程序接口表的格式说明和作用

AI Table 首先全拼不是AI人工智能表&#xff0c;而是Application Interface Table应用程序接口表。此表按照AUTOSAR的格式规范去定义&#xff0c;并且使用此Excel 表格生成相应的应用软件组件Arxml文件。下面就让我们按照AUTOSAR_EXP_AIUserGuide.pdf文档官方解释描述文件去看看…

Python--装饰器

在 Python 中&#xff0c;装饰器是一种特殊类型的函数&#xff0c;它们用于修改或增强其他函数或方法的行为。装饰器本质上是一个函数&#xff0c;它接受一个函数作为参数&#xff0c;并返回一个新的函数。使用装饰器可以在不修改原函数代码的前提下&#xff0c;给函数添加新的…

数据结构实战:变位词侦测

文章目录 一、实战概述二、实战步骤&#xff08;一&#xff09;逐个比较法1、编写源程序2、代码解释说明&#xff08;1&#xff09;函数逻辑解释&#xff08;2&#xff09;主程序部分 3、运行程序&#xff0c;查看结果4、计算时间复杂度 &#xff08;二&#xff09;排序比较法1…