当前位置: 首页 > news >正文

NO.97十六届蓝桥杯备战|数论板块-最大公约数和最小公倍数|欧几里得算法|秦九韶算法|小红的gcd(C++)

约数和倍数
  • 如果a 除以b 没有余数,那么a 就是b 的倍数,b 就是a 的约数,记作b ∣ a 。
    约数,也称因数。
最⼤公约数和最⼩公倍数

最⼤公约数Greatest Common Divisor,常缩写为gcd。

  • ⼀组整数的公约数,是指同时是这组数中每⼀个数的约数的数。
  • ⼀组整数的最⼤公约数,是指所有公约数⾥⾯最⼤的⼀个。
    最⼩公倍数Least Common Multiple,常缩写为lcm。
  • ⼀组整数的公倍数,是指同时是这组数中每⼀个数的倍数的数。
  • ⼀组整数的最⼩公倍数,是指所有正的公倍数⾥⾯,最⼩的⼀个数。
    求两个数的gcd与lcm时,有如下性质:
  • 对于两个数a和b ,gcd(a, b) × lcm(a, b) = a × b。也就是最⼤公约数乘以最⼩公倍数等于两个数的乘积。
    因此,⼀般先求最⼤公约数,然后⽤这个性质求最⼩公倍数。
欧⼏⾥得算法

欧⼏⾥得算法也称辗转相除法,可以求出两个整数的最⼤公约数。
算法流程:
设a > b :

  • 如果b 是a 的约数,那么b 就是两者的最⼤公约数;
  • 如果b 不是a 的约数,那么gcd(a, b) = gcd(b, a mod b)
    因为a mod b 会不断减⼩,因此可以⽤递归进⾏求解
LL gcd(LL a, LL b)  
{  if(!b) return a; // 如果 b 等于 0,说明 a 就是最⼤公约数  return gcd(b, a % b);  
}

时间复杂度:
求gcd(a, b) 会遇到两种情况:

  1. a < b ,则gcd(a, b) = gcd(b, a)
  2. a > b ,则gcd(a, b) = gcd(b, a mod b)
    第⼆种情况会让a ⾄少折半,因此最多执⾏log n 次。
    第⼀种情况不会多于第⼆种,因此时间复杂度为O(log n)

证明gcd(a, b) = gcd(b, a mod b) ,思路:先证左边等于右边,再证右边等于左边。
设a > b ,a mod b = a - kb ,其中k = a/b ,为整数:

  1. 若d是(a, b)的公约数,则d | a且d | b ,于是d | (a - kb) ,则d | (a mod b) ;因此d也是(b, a mod b) 的公约数;
  2. 若d是(b, a mod b)的公约数,则d∣b且d∣(a - kb) ,于是d∣(a - kb + kb) = d∣(a) ;因此d也是(a, b)的公约数;
    所以(a, b) 的公约数与(b, a mod b) 的公约数相同,那么最⼤公约数也相同
B3736 [信息与未来 2018] 最大公约数 - 洛谷

三个数的最⼤公约数,先求其中两个的gcd,再与第三个求gcd

#include <bits/stdc++.h>
using namespace std;int gcd(int a, int b)
{return b == 0 ? a : gcd(b, a % b);
}int main()
{ios::sync_with_stdio(false);cin.tie(0);int x, y, z; cin >> x >> y >> z;cout << gcd(gcd(x, y), z) << endl;return 0;
}
小红的 gcd

先将⼤数取模,然后再代⼊公式计算

秦九韶算法
秦九韶算法是⼀种将⼀元n次多项式的求值问题转化为n个⼀次式的算法。其⼤⼤简化了计算过程,即使在现代,利⽤计算机解决多项式的求值问题时,秦九韶算法依然是最优的算法
![[Pasted image 20250418145708.png]]

例如:对于⼀个整数987654321 ,可以拆成:
( ( ( ( ( ( ( 9 × 10 + 8 ) × 10 + 7 ) × 10 + 6 ) × 10 + 5 ) × 10 + 4 ) × 10 + 3 ) × 10 + 2 ) × 10 + 1 (((((((9 × 10 + 8) × 10 + 7) × 10 + 6) × 10 + 5) × 10 + 4) × 10 + 3) × 10 + 2) × 10 + 1 (((((((9×10+8)×10+7)×10+6)×10+5)×10+4)×10+3)×10+2)×10+1
这样对于⾼精度的数取模,就可以分阶段取模

#include <bits/stdc++.h>
using namespace std;string a; int b;int gcd(int a, int b)
{return b == 0 ? a : gcd(b, a % b);
}int calc()
{long long t = 0;for (auto ch : a){t = t * 10 + ch - '0';t %= b;}return t;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> a >> b;cout << gcd(b, calc()) << endl;return 0;
}

相关文章:

  • 爬虫学习——Scrapy
  • Java编程语言 1.打印数组元素 2.Student类 StudentTest类
  • 【go】什么是Go语言中的GC,作用是什么?调优,sync.Pool优化,逃逸分析演示
  • alertManager部署安装、告警规则配置详解及告警消息推送
  • 华为openEuler操作系统全解析:起源、特性与生态对比
  • 机器学习模型(2/4课时):损失函数
  • 深度学习中的卷积神经网络
  • 命令行工具kubectl
  • 密码学中的盐值是什么?
  • RAII资源管理理解
  • Python 中的数据类型有哪些
  • 每日算法-250418
  • 智能化印刷新时代:Modbus 转profinet网关的完美融合,提升生产效率与环保标准
  • LangChain4j-第一篇 |几分钟完成deepseek 在线集成
  • 数据资产登记导则详解 | 企业如何规范化登记与管理数据资产?
  • ubuntu-24.04.2-live-server-arm64基于cloud-init实现分区自动扩容(LVM分区模式)
  • Selenium之 CSS 选择器详细讲解
  • 【笔记】【C++】【基础语法】作用域(scope)、持续时间(duration)和链接(linkage)
  • ChatGPT-o3辅助学术大纲效果如何?
  • 【linux学习】 Redhat9.5安装
  • 第一集|《蛮好的人生》蛮好,《悬镜》挺玄
  • 心源性猝死正“猎杀”年轻人,这几招保命法则要学会
  • 东北三省,十年少了一个“哈尔滨”
  • 谷雨播种正当时,上海黄道婆纪念公园种下“都市棉田”
  • 澳门世界杯“中日对决”,蒯曼击败伊藤美诚晋级女单决赛
  • 遭遇FIFA三个转会窗禁令,申花有苦难言将选择赔偿