求最大公约数【C/C++】
大家好啊,欢迎来到本博客( •̀ ω •́ )✧,我将带领大家详细的了解最大公约数的思想与解法。
一、什么是公约数
公约数,也称为公因数,是指两个或多个整数共有的因数。具体来说,如果一个整数能被两个或多个整数整除,那么这个整数就是这些整数的公约数。
例如,考虑整数12和18:
-
12的因数有 :1, 2, 3, 4, 6, 12
-
18的因数有:1, 2, 3, 6, 9, 18
12和18的公约数是它们共有的因数,即:1, 2, 3, 6
二、计算最大公约数的方法:
学习数论的一系列算法时,往往直接看算法,是看不懂的。
这里我们先学习数学解法、在给出算法。
1、辗转相除法:(欧几里得算法)
数学:
假设我们有两个正整数 a 和 b,其中 a>b。根据辗转相除法,最大公约数 gcd(a,b) 可以通过以下步骤求得:
-
第一步:计算 a mod b,得到余数 r。
-
第二步:将 a 替换为 b,将 b 替换为 r。
-
第三步:重复上述步骤,直到 b=0 时,此时 a 即为最大公约数。
下方用(18、12)举例。
如图:
代码:
简约背诵版:
#include "iostream"
using namespace std;
// 求公约数
int gcd(int a, int b){while(a%b!=0){int c = a%b;a=b;b=c;}return b;
}int main(){int a,b;a = 18;b = 12;cout<<func(a,b)<<endl;return 0;
}
解释版:
// 包含输入输出流头文件,用于使用 cin 和 cout 进行输入输出操作
#include <iostream>// 使用标准命名空间,这样就可以直接使用标准库中的类和函数,而无需加 std:: 前缀
using namespace std;/*** 函数功能:计算两个整数的最大公约数(Greatest Common Divisor, GCD)* 参数:* a: 第一个整数* b: 第二个整数* 返回值:* a 和 b 的最大公约数* 算法:使用欧几里得算法(辗转相除法)来计算最大公约数* 原理:两个整数 a 和 b(a > b)的最大公约数等于 b 和 a % b 的最大公约数*/
int gcd(int a, int b) {// 当 a 除以 b 的余数不为 0 时,继续循环while (a % b != 0) {// 计算 a 除以 b 的余数,并将其存储在变量 c 中int c = a % b;// 将 b 的值赋给 aa = b;// 将余数 c 的值赋给 bb = c;}// 当循环结束时,b 即为 a 和 b 的最大公约数,将其返回return b;
}int main() {// 定义两个整型变量 a 和 b,用于存储要计算最大公约数的两个数int a, b;// 给变量 a 赋值为 18a = 18;// 给变量 b 赋值为 12b = 12;// 调用 gcd 函数计算 a 和 b 的最大公约数,并将结果输出到控制台cout << gcd(a, b) << endl;// 程序正常结束,返回 0 表示成功return 0;
}
2、更相减损版(辗转相减法)
数学:
更相减损法是一种古老的算法,用于求两个正整数的最大公约数(GCD)。它最早出现在中国古代数学著作《九章算术》中。以下是更相减损法的数学用法和原理:
更相减损法的基本原理是:对于任意两个正整数 a 和 b(假设 a≥b),如果 a 和 b 都是偶数,则可以用 2 约简;如果 a 和 b 不都是偶数,则用较大的数减去较小的数,然后继续对所得的差和较小的数进行同样的操作,直到两个数相等为止。这个相等的数就是它们的最大公约数。
如图:
代码:
简约背诵版:
#include "iostream"
using namespace std;int func(int a, int b){while(a-b!=0){int c = a - b;a = b;b = c;}return a;
}int main(){int a,b;a = 18;b = 12;cout<<func(a,b)<<endl;return 0;
}
解释版:
// 引入标准输入输出流头文件,该头文件提供了像 cin 和 cout 这样的输入输出功能
// 注意:这里使用双引号包含头文件通常用于自定义头文件,标准库头文件一般用尖括号,应改为 #include <iostream>
#include "iostream"// 使用标准命名空间 std,这样在后续代码里就可以直接使用标准库中的类和函数,无需添加 std:: 前缀
using namespace std;/*** 函数名: func* 功能: 计算两个整数的最大公约数(Greatest Common Divisor, GCD)* 参数:* a: 第一个整数* b: 第二个整数* 返回值:* a 和 b 的最大公约数* 算法: 采用更相减损术来计算最大公约数* 原理: 两个正整数 a 和 b(a > b)的最大公约数等于 b 和 a - b 的最大公约数*/
int func(int a, int b) {// 只要 a 与 b 的差值不为 0,就持续循环while (a - b != 0) {// 计算 a 减去 b 的差值,并将结果存储在临时变量 c 中int c = a - b;// 把 b 的值赋给 aa = b;// 把差值 c 的值赋给 bb = c;}// 当 a 与 b 的差值为 0 时,说明此时 a 和 b 相等,这个相等的值就是 a 和 b 的最大公约数,将其返回return a;
}/*** 函数名: main* 功能: 程序的入口函数,程序从这里开始执行* 参数: 无* 返回值:* 整数 0,表示程序正常结束*/
int main() {// 声明两个整型变量 a 和 b,用于存储要计算最大公约数的两个数int a, b;// 给变量 a 赋值为 18a = 18;// 给变量 b 赋值为 12b = 12;// 调用 func 函数计算 a 和 b 的最大公约数,并将结果输出到标准输出流(通常是控制台)// 输出完成后换行cout << func(a, b) << endl;// 返回 0 表示程序正常结束return 0;
}
3、其他方法:
其他方法不像(辗转相除法与更相减损法)那么简便。
所以我在这里,只简单的介绍一下:
1、分解质因数
#include<stdio.h>
void fun(int * arr,int n)
{int i = 2, j = 0;while (n > 1){if (n % i == 0){arr[j++] = i;n /= i;}else {i++;}}
}
int gcd(int a,int b)
{//因为要进行找这个数的共有的因数,所以这里用数组来接收int arr_a[100] = {0};//放a的所有因数int arr_b[100] = {0};//放b的所有因数//进行放因数fun(arr_a,a);fun(arr_b,b);//找出公共的因数,然后相乘int i = 0, j = 0, ret = 1;while (arr_a[i] != 0 && arr_b[j] != 0) {if (arr_a[i] == arr_b[j]) {ret *= arr_a[i];i++;j++;}else if (arr_a[i] > arr_b[j]){j++;}else{i++;}}return ret;
}
int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int ret = gcd(a,b);//最大公因数printf("%d和%d的最大公因数是:%d",a,b,ret);return 0;
}
2、穷举法
法如其名,一个一个的输入测试,最后取出来。
//穷举法
#include<stdio.h>
int main()
{int a = 0;int b = 0;scanf("%d %d",&a,&b);int t = a;while (t--){if (a % t == 0 && b % t == 0)break;}printf("%d",t);return 0;
}
3、递归法
简单来说,递归法其实就是模拟了辗转相除法。
#include "iostream"
using namespace std;int gcd(int a, int b){if(a%b==0){ // 得到余数return b;}else{ // 余数为0进入递归return gcd(b,a%b); // b放到a的位置,a/b的余数放到b的位置 }
}
int main(){int a,b;a = 18;b = 12;cout<<gcd(a,b)<<endl;return 0;
}
三、练习:
等差数列
题目描述
数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一 部分的数列,只记得其中 NN 个整数。
现在给出这 NN 个整数,小明想知道包含这 NN 个整数的最短的等差数列有几项?
输入描述
输入的第一行包含一个整数 NN。
第二行包含 NN 个整数 A1,A2,⋅⋅⋅,ANA1,A2,⋅⋅⋅,AN。(注意 A1A1 ∼ ANAN 并不一定是按等差数列中的顺序给出)
其中,2≤N≤105,0≤Ai≤1092≤N≤105,0≤Ai≤109。
输出描述
输出一个整数表示答案。
输入输出样例
示例
输入
5 2 6 4 10 20
输出
10
样例说明: 包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、 18、20
这道题目说难不难,说简单不简单
1、很多人不会想到用gcd解题,甚至是直接暴力解题,欸!我一会也试试:(vec[n-1]-vec[0])/n,看来是不行的(n不是所有个数)。但是也能用最小差值作为间隔呀,如:d = min(d,gcd(dif[i],dif[i+1])); 这样好像也行,一会试试
2、当然就是这个啦d = min(d,vec[i+1]-vec[i]); 好多人没考虑min,细节容易出错。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;// 通过递归
int gcd(int a, int b){if(a%b==0){return b;}else{return gcd(b,a%b);}
}int main()
{int n;cin>>n;vector<int> vec(n);for(int i=0; i<n; ++i){cin>>vec[i];}if(vec.size()==2){ // 特殊情况,只有两个数cout<<2<<endl;return 0;}sort(vec.begin(), vec.end());vector<int> dif(n-1); // 差集数列for(int i=0; i<vec.size()-1; ++i){dif[i] = vec[i+1]-vec[i];}int d = dif[0];if(d==0){ // 有没有一种可能,差值为0。cout<<n<<endl;return 0;}for(int i=0; i<dif.size()-1; ++i){ // 所有差集的最大公约数d = min(d,gcd(dif[i],dif[i+1])); // 为防止结果处,出现更大的差值。}int num = (vec[vec.size()-1]-vec[0])/d; // d 为0的情况,已经被排除if(d==num){cout<<vec.size()<<endl;}else{cout<<num+1<<endl;}return 0;
}
笔者感悟:
学习数论的一系列算法时,往往直接看算法,是看不懂的。
需要先摸清数学思想,胸有成竹之时,写对应算法就更轻松、也记得更牢固。
别人算法理解不透的时候,往往是基础扎的不够牢固。
借鉴博客/视频:
1、求最大公约数的几种常见的方法 【详解】
相关文章:

求最大公约数【C/C++】
大家好啊,欢迎来到本博客( •̀ ω •́ )✧,我将带领大家详细的了解最大公约数的思想与解法。 一、什么是公约数 公约数,也称为公因数,是指两个或多个整数共有的因数。具体来说,如果一个整数能被两个或多个整数整除&…...

leetcode day27 455+376
455 分发饼干 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有…...

go的grpc
GRPC介绍 目录 单体架构微服务架构问题原始的grpc 服务端客户端原生rpc的问题 grpc的hello world 服务端客户端 proto文件proto语法 数据类型 基本数据类型其他数据类型 编写风格多服务 单体架构 只能对整体扩容一荣俱荣,一损俱损代码耦合,项目的开…...

算法每日一练 (9)
💢欢迎来到张胤尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 算法每日一练 (9)最小路径和题目描述解题思路解题代码…...

软考高级信息系统项目管理师笔记-第10章项目进度管理
第10章项目进度管理 10.1 管理基础 10.1.1 项目进度计划的定义和总要求 1、项目进度计划是 一种用于沟通和管理干系人期望的工具,为绩效报告提供依据。 2、项目管理团队编制进度计划的一般步骤为: 首先选择进度计划方法,例如关键路径法; 然后将项目特定数据,如活动、计…...

专门为高速连续扫描设计的TDI工业相机
TDI(Time Delay Integration,时间延迟积分)工业相机是一种基于特殊CCD(电荷耦合器件)技术的成像设备,主要用于高速、高灵敏度、高分辨率的图像采集场景。其核心原理是通过多级积分和同步电荷转移技术&#…...

【Vue3】实现一个超过高度后可控制显示隐藏的组件
组件效果图 未达到最大高度 达到设置的最大高度 进行展开 实现代码 组件代码 备注:通过tailwindcss设置的样式,通过element-plus/icons-vue设置的图标,可根据情况进行替换 <template><!-- 限制高度组件 --><div ref"…...

Spring提供的SPEL表达式
SPEL 1. 概述 SpEL是Spring框架中用于表达式语言的一种方式。它类似于其他编程语言中的表达式语言,用于在运行时计算值或执行特定任务。 SpEL提供了一种简单且强大的方式来访问和操作对象的属性、调用对象的方法,以及实现运算、条件判断等操作。它可以…...

JAVA编程【jvm垃圾回收的差异】
jvm垃圾回收的差异 JVM(Java Virtual Machine)的垃圾回收(GC)机制是自动管理内存的一种方式,能够帮助开发者释放不再使用的内存,避免内存泄漏和溢出等问题。不同的垃圾回收器(GC)有…...

Elasticsearch:“Your trial license is expired”
目录标题 问题原因解决方案 问题 原因 ES的X-pack许可证是提供免费一个月的试用,到期之后就会报这个错误。 解决方案 查看license GET _license 开启试用license POST _xpack/license/start_trial?acknowledgetrue修改为基础license POST _xpack/license/start_…...

fmql之Linux WDT
正点原子第52章。 基础知识 正点原子教程 fmql-dts 代码 APP代码(不需要编写驱动代码) static int dw_wdt_drv_probe(struct platform_device *pdev) {struct device *dev &pdev->dev;struct watchdog_device *wdd;struct dw_wdt *dw_wdt; …...

【算法学习之路】7.链表算法
链表算法 前言一.原地逆置思路一:头插法思路二:双指针法思路3:递归 例题:1.头插法2.双指针法3,递归 二.双指针快慢指针:一个指针快一个指针慢例题1例题2 前言 我会将一些常用的算法以及对应的题单给写完&am…...

IDEA Commit 模态提交界面关闭VS开启对比
IDEA Commit 模态提交界面关闭VS开启对比 前言开启模态提交界面优点快捷且灵活的选择需要commit文件显示文件修改内容多(主观) 缺点在模态提交界面选择文件,临时关闭模态框重新打开会重置选择的commit文件 关闭模态提交界面优点允许在commit选择文件时查看其它没有修…...

【AI赋能】AI 工具生成视频教材:从创意到成品的全流程指南
AI 工具生成视频教材:从创意到成品的全流程指南 目标 通过本教材,您将学会如何利用 AI 工具(Grok、Sora、Speechify 和 CapCut)生成一个完整的视频,包括脚本生成、视频片段制作、字幕添加、音频生成以及最终剪辑合成…...

qt 操作多个sqlite文件
qt 操作多个sqlite文件 Chapter1 qt 操作多个sqlite文件1. 引入必要的头文件2. 创建并连接多个SQLite数据库3. 代码说明4. 注意事项 Chapter2 qt 多线程操作sqlite多文件1. 引入必要的头文件2. 创建数据库操作的工作线程类3. 在主线程中创建并启动多个工作线程4. 代码说明5. 运…...

WSL with NVIDIA Container Toolkit
一、wsl 下安装 docker 会提示安装 docekr 桌面版,所以直接安装 docker 桌面版本即可 二、安装 NVIDIA Container Toolkit NVIDIA Container Toolkit仓库 https://github.com/NVIDIA/nvidia-container-toolkitgithub.com/NVIDIA/nvidia-container-toolkit 安装…...

Vue 系列之:组件通讯
子组件调用父组件方法 1、直接在子组件中通过 this.$parent.event 来调用父组件的方法 父组件: <template><p><child></child></p> </template> <script>import child from ./child;export default {components: {chi…...

【Linux实践系列】:用c语言实现一个shell外壳程序
🔥本文专栏:Linux Linux实践项目 🌸博主主页:努力努力再努力wz 那么今天我们就要进入Linux的实践环节,那么我们之前学习了进程控制相关的几个知识点,比如进程的终止以及进程的等待和进程的替换,…...

STL map 的 lower_bound(x)、upper_bound(x) 等常用函数
【STL map 简介】 ● STL map 是一种关联容器,存储键值对,每个键(key value)是唯一的,而值(mapped value)可以重复。构建 STL map 时,无论元素插入顺序如何,STL map 中的…...

【A2DP】SBC 编解码器互操作性要求详解
目录 一、SBC编解码器互操作性概述 二、编解码器特定信息元素(Codec Specific Information Elements) 2.1 采样频率(Sampling Frequency) 2.2 声道模式(Channel Mode) 2.3 块长度(Block Length) 2.4 子带数量(Subbands) 2.5 分配方法(Allocation Method) 2…...

Computational Linguistics期刊全解析:领域顶刊的投稿指南与学术价值
在人工智能与语言学交叉融合的浪潮中,《Computational Linguistics》(CL)作为该领域的标杆期刊,始终是研究者发表前沿成果的首选平台。本文将从期刊影响力、投稿策略、收稿方向等角度,为学者提供一份全面的指南。 一、…...

【量化科普】Sharpe Ratio,夏普比率
【量化科普】Sharpe Ratio,夏普比率 🚀量化软件开通 🚀量化实战教程 在量化投资领域,夏普比率(Sharpe Ratio)是一个非常重要的风险调整后收益指标。它由诺贝尔经济学奖得主威廉F夏普(William…...

运行OpenManus项目(使用Conda)
部署本项目需要具备一定的基础:Linux基础、需要安装好Anaconda/Miniforge(Python可以不装好,直接新建虚拟环境的时候装好即可),如果不装Anaconda或者Miniforge,只装过Python,需要确保Python是3.…...

TikTok Shop欧洲市场爆发,欧洲TikTok 运营网络专线成运营关键
TikTok在欧洲的影响力还在持续攀升,日前,TikTok发布了最新的欧盟执行和使用数据报告,报告中提到: 2024年7~12月期间,TikTok在欧盟地区的月活用户达1.591亿,较上一报告期(2024年10月发布…...

基于YOLO11深度学习的电瓶车进电梯检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

计算机毕业设计SpringBoot+Vue.js制造装备物联及生产管理ERP系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

微服务保护:Sentinel
home | Sentinelhttps://sentinelguard.io/zh-cn/ 微服务保护的方案有很多,比如: 请求限流 线程隔离 服务熔断 服务故障最重要原因,就是并发太高!解决了这个问题,就能避免大部分故障。当然,接口的并发…...

labelimg标注的xml标签转换为yolo格式标签
本文不生产技术,只做技术的搬运工!!! 前言 在yolo训练时,我们需要对图像进行标注,而使用labelimg标注时如果直接选择输出yolo格式的数据集,则原始数据的很多信息无法被保存,因此一版…...

VUE3开发-9、axios前后端跨域问题解决方案
VUE前端解决跨域问题 前端页面需要改写 如果无效,记得重启服务器 后端c#解决跨域问题 前端js取值,后端c#跨域_c# js跨域-CSDN博客...

机试准备第12天
首先学习队列,队列有先进先出的特性。广度优先遍历需要基于队列实现,C中的stl引入了队列的实现方式。队列支持push(),进入队尾,pop()出队,队头出队,front()获取队首元素,back()获取队尾元素&…...