A30161.【循环】 最小公倍数
2026-05-16 19:20:02
发布于:福建
7阅读
0回复
0点赞
求两数最小公倍数 题解
这题太水了,但是为了追求极致的时间复杂度与空间复杂度,我也是用了20分钟(╥╯^╰╥)
可以点个赞吗,求求了
一、前置知识:
欧几里得算法(辗转相除法)求最大公约数(gcd) ,时间复杂度为 。
核心原理
欧几里得算法基于一个关键性质:对于任意两个正整数 和 (),有 。
- 反复用较大数对较小数取余,直到余数为 ,此时的非零余数即为两数的最大公约数。
- 时间复杂度为 ,因为每一次取余操作都会将数值缩小至少一半,运算步数极少(即使是题目上限 ,最多只需30次左右运算)。
示例
求 :
- 余数为 ,最终最大公约数为 。
二、题目大意
给定两个不超过 的正整数,求出二者的最小公倍数(lcm) 并输出。
三、解题思路
- 利用数论核心结论(基于前置知识推导):
- 关键优化(防溢出):由于题目中数值最大可达 ,直接计算 会超出整数范围,因此改写为安全写法:(先除后乘,确保中间结果不溢出)。
- 用欧几里得算法实现快速求最大公约数,结合手写快读、快写优化输入输出速度,实现极致性能。
四、算法复杂度
- 求最大公约数:,对数级效率,接近常数级。
- 整体时间复杂度:(由求最大公约数的复杂度主导)。
- 空间复杂度:,仅使用少量临时变量,无额外内存开销。
五、核心原理(补充)
- 最小公倍数推导:
由前置知识可知,两个数的乘积等于其最大公约数与最小公倍数的乘积,即:
对公式变形,即可得到最小公倍数的计算方式,这是本题的核心推导依据。
- 欧几里得算法的极简实现:
代码中使用位运算简写辗转相除逻辑while(b) b ^= a ^= b ^= a %= b;,本质等价于:
while (b != 0) {
long long temp = a % b;
a = b;
b = temp;
}
return a;
简写形式无逻辑差异,但代码更精简,运算效率更高。
六、完整AC代码(不要直接抄标程哦)
#include<cstdio>
inline long long gcd(long long a,long long b){
while(b)b^=a^=b^=a%=b;
return a;
}
inline long long read(){
long long x=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
return x;
}
inline void w(long long x){
if(x>9)w(x/10);
putchar(x%10+'0');
}
int main(){
long long n=read(),m=read();
w(n/gcd(n,m)*m);
}
七、代码详解
1. gcd 函数(欧几里得算法实现)
- 用
inline关键字修饰,将函数内联嵌入主代码,消除函数调用的额外开销。 - 采用位运算简写辗转相除逻辑,代码极度精简,运算效率拉满,完全贴合前置知识中的欧几里得算法原理。
2. 快读函数 read()
- 直接调用
getchar()逐字符读取输入,跳过非数字字符,避免标准IO(scanf)的缓冲区冗余开销,速度远超标准输入。 - 逐位拼接数字(),完美适配题目中超大整数(不超过 )的读取需求。
3. 快写函数 w()
- w是write的简写,是写的意思
- 用递归拆分数字(将大数拆分为个位和剩余部分),通过
putchar()逐字符输出,是C语言中最快的输出方式,避免标准输出(printf)的冗余开销。
4. 主函数逻辑
- 用快读函数读取两个输入整数 和 ;
- 调用
gcd函数求出两数的最大公约数; - 用安全公式 计算最小公倍数;
- 用快写函数输出结果,全程无冗余操作。
八、极致优化亮点
- IO 极限优化:手写快读、快写,彻底绕过C语言标准IO的缓冲区开销,在OJ评测机上稳定运行 ,是C++中最快的输入输出方式。
- 运算防溢出:采用
n/gcd(n,m)*m的计算顺序,先除以最大公约数缩小数值,再乘以另一个数,杜绝超大数直接相乘导致的溢出问题。 - 语法精简优化:内联函数+位运算简写,最大限度减少机器指令,降低内存占用(最终内存消耗仅 )。
- 数据类型适配:统一使用
long long类型,全覆盖题目给定的数值范围(),避免数据溢出。
九、易错点提醒
- 严禁将公式写为
n * m / gcd(n,m):当 和 均为题目上限时, 会超出long long范围,导致溢出报错。 - 快读函数必须添加
c = getchar()向后移动字符指针:若遗漏,会一直读取同一个字符,导致程序卡死。 - 数据类型不能用
int:int的最大值为 ,刚好等于题目中数值的上限,计算过程中容易溢出,必须用long long。 - 欧几里得算法无需提前交换 和 的大小:算法本身会通过取余操作自动调整两数的大小关系,无需额外添加交换逻辑。
十、评测表现
- 时间复杂度为
- 空间复杂度为
- 执行用时:(评测机计时下限,理论最快速度,无法超越);
- 内存消耗:,内存击败100%用户;
- 可以通过提交一遍代码检验是否准确
- 测试覆盖:全范围数据无错,稳定AC所有测试点,适配题目所有边界情况(如两数相等、两数互质、其中一个数为1等)。
这里空空如也



有帮助,赞一个