浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用
一、欧几里得算法及其证明
1.定义:
欧几里得算法又称辗转相除法,用于求两数的最大公约数,计算公式为GCD(a,b)=GCD(b,a%b);
2.证明:
设x为两整数a,b(a>=b)的最大公约数,那么x|a,x|b;
①由整数除法具有传递性(若x能整除a,x能整除b,那么x可整除a,b的任意线性组合)知x|a-b;
②设x不是b的因子,则x不是b和a-b的公因子;设x不是a的因子,则x不是b和a-b的公因子;所以可以得出GCD(a,b)=GCD(b,a-b);
③由a>=b知,a可表示为a=b*q+r;则a减去q个b剩下的数字即为r,所以GCD(a,b)=GCD(b,a%b);
3.一般代码:
(1)递归形式:
int gcd(int a,int b){return b?gcd(b,a%b):a;}
(2)迭代形式:
int gcd(int a,int b){ for(;;) { if(b==0)return a; int temp=a%b; a=b;b=temp;} }
4.几个性质:
(1)若GCD(a,b)=1,那么a,b两数互质。
(2)GCD(a,2a)=a;
(3)GCD(a,0)=a;
(4)GCD(a,b)=GCD(-a,b)=GCD(a,-b)=GCD(-a,-b);
(5)LCM(a,b)GCD(a,b)=ab(LCM为两数小公倍数);
(6)GCD(n,n+1)=1;
证明:
假设他们不是互素的,有公共因子q
n = p1 * 1,n + 1 = p2 * q;n+1 - n = q(p2 - p1)
则q(p2-p1) = 1;其中p2,p1均为整数,q >=2,可证不等。得证。
二、相关题目
1.[洛谷P1372]又是毕业季I
Description
老师想要挑出默契程度最大的k个人参与毕业晚会彩排。可是如何挑呢?老师列出全班同学的号数1,2,……,n,并且相信k个人的默契程度便是他们的最大公约数(这不是迷信哦~)。这可难为了他,请你帮帮忙吧!PS:一个数的最大公约数即本身。
输入格式:两个空格分开的正整数n和k。(n>=k>=1)
输出格式:一个整数,为最大的默契值。
Solution
1.注意:“一个数的最大公约数即本身”:我们可以从性质(2)考虑:当两个数是倍数时,最大公约数即为较小的数,那么此时相对同一范围的其他组合这两个数的最大公约数相对较大。
2.在讨论几种特殊情况:k=1时,ans=n;k=2时,若n为偶数,则ans=n/2,若n为奇数,则ans=(n-1)/2;
3.有上述讨论我们发现:满足k*a<n的a的最大值即为答案。即选中的数字分别为a,2a,3a,......,ka,所以答案为a/b;
Code
#include<iostream>
using namespace std;
int main()
{int a,b;cin>>a>>b;cout<<a/b<<"\n";return 0;
}
2.[洛谷P1170]兔八哥与猎人
Description
兔八哥躲藏在树林旁边的果园里。果园有M × N棵树,组成一个M行N列的矩阵,水平或垂直相邻的两棵树的距离为1。兔八哥在一棵果树下。猎人背着猎枪走进了果园,他爬上一棵果树,准备杀死兔八哥。如果猎人与兔八哥之间没有其它的果树,猎人就可以看到兔八哥。现己知猎人和兔八哥的位置,编写程序判断兔子所在的位置是否安全.
输入格式:第一行为n,表示有n(n ≤ 100,000)组数据,每组数据的第一行为两个正整数ax和ay,表示猎人的位置,第二行为两个正整数bx和by,表示兔八哥的位置(1 ≤ ax, ay, bx, by ≤ 100,000,000)。
输出格式:共有n行,每行为“yes”或“no”表示兔八哥的位置是否安全。
Solution
1.读题后我们可以将题目化简:求两坐标为整数的点确定的直线上两点间是否还存在另一坐标均为整数的点;
2.那么我们可以以猎人的坐标为原点,建立坐标系,设猎人(x1,y1),兔子(x2,y2),那么我们把兔子的坐标改为(x2-x1,y2-y1);
3.那么如何确定该点与原点间没有其他坐标为整数的点呢?通过画图我们可以发现,只要该点坐标互质即能满足要求,由性质(1)知等价于GCD(x,y)=1;
4.由性质(4)我们知道,两数的符号号并不影响它们的最大公约数所以对坐标取绝对值再计算;
5.注意本题有多组数据;
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int gcd(int a,int b){return b?gcd(b,a%b):a;} //GCD;
int main(){int n,x1,x2,y1,y2,i,j,k;scanf("%d",&n);for(i=1;i<=n;++i){scanf("%d%d%d%d",&x1,&y1,&x2,&y2);if(x1==x2&&y1==y2){ //特判,两者坐标重合时,GCD=0,而兔子有危险;printf("no\n");continue;}x2=abs(x2-x1);y2=abs(y2-y1);if(gcd(x2,y2)==1)printf("no\n");else printf("yes\n");}return 0;
}
3.[洛谷P2651]添加括号III
Description
现在给出一个表达式,形如a1/a2/a3/.../an;如果直接计算,就是一个个除过去,比如1/2/1/4=1/8。然而小A看到一个分数感觉很不舒服,希望通过添加一些括号使其变成一个整数。一种可行的办法是(1/2)/(1/4)=2。现在给出这个表达式,求问是否可以通过添加一些括号改变运算顺序使其成为一个整数。
输入格式:一个测试点中会有多个表达式。第一行t,表示表达式数量。对于每个表达式,第一行是n,第二行n个数,第i个数表示ai。
输出格式:输出t行。对于每个表达式,如果可以通过添加括号改变顺序使其变成整数,那么输出“Yes”,否则输出“No”
Solution
1.我们可以发现,为了使其结果尽可能为整数,我们应使分母最大,分子最小;
2.那么我们发现,a2无论如何都是在分母上的,那么我们这样添加括号即可:a1/(a2/a3/.../an)=a1a3...*an/a2,此时满足分母最大,分子最小;
3.那么我们需要进行约分:对每一个分子都和分母求一次GCD,每次求后令分母除以GCD,到最后一项时若分母=1,则结果为整数;
4.注意本题有多组数据;
Code
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int gcd(int a,int b){return b?gcd(b,a%b):a;} //GCD
int main(){int t,n,i,j;scanf("%d",&t);for(i=1;i<=t;++i){scanf("%d",&n);int a[n+1]={};for(j=1;j<=n;++j) scanf("%d",&a[j]);a[2]/=gcd(a[1],a[2]);for(j=3;j<=n;++j) a[2]/=gcd(a[2],a[j]);if(a[2]==1)printf("Yes\n");else printf("No\n");}return 0;
}
4.[洛谷P1029]最大公约数与最小公倍数问题
题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8514163.html
5.[CodePlus 2017 11月赛]晨跑
题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8514190.html
6.[BZOJ 2257][JSOI 2009] 瓶子和燃料
题解随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8995031.html
转载于:https://www.cnblogs.com/COLIN-LIGHTNING/p/8371664.html
浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用相关推荐
- 浅谈Stein算法求最大公约数(GCD)的原理及简单应用
一.Stein算法过程及其简单证明 1.一般步骤: s1:当两数均为偶数时将其同时除以2至至少一数为奇数为止,记录除掉的所有公因数2的乘积k: s2:如果仍有一数为偶数,连续除以2直至该数为奇数为止: ...
- 离散数学/初等数论:用“质因子分解法”和“欧几里得算法”求最大公约数gcd;“质因子分解法”和“最简算法”求最小公倍数lcm;以及对“意义”的一些看法。
需要在开头提前说明,本篇文章仅仅用于在学习初等数论或者离散数学时候对算术基本定理的理解,实际应用的时候把结论告诉大家,想求最大公约数就用欧几里得算法是最简单的,在本篇不再赘述,有机会我会在其他文章中说 ...
- 用欧几里得算法求最大公约数_欧几里得算法:GCD(最大公约数),用C ++和Java示例解释...
用欧几里得算法求最大公约数 For this topic you must know about Greatest Common Divisor (GCD) and the MOD operation ...
- 欧几里得算法求最大公约数、最大公倍数
欧几里得算法求最大公约数.最大公倍数 最大公约数(Greatest Common Divisor, GCD),是指2个或N个整数共有约数中最大的一个.a,b的最大公约数记为(a, b).相对应的是最小 ...
- 欧几里得算法求最大公约数python,算法:欧几里得求最大公约数(python版)
#欧几里得求最大公约数 #!/usr/bin/env python #coding -*- utf:8 -*- #iteration def gcd(a,b): if b==0: return a e ...
- 欧几里得算法求最大公约数之惊掉下巴的代码简化(纯C语言)
欧几里得算法求最大公约数也叫辗转相除法. 证明 有两个数a,b,且a = kb + r(a,b,k,r皆为正整数,且r<b) 假设d为a,b的一个公约数 而r = a - kb,两边同时除以d, ...
- 辗转相除法(欧几里得算法)求 最大公约数与最小公倍数+推论与证明。
首先我们规定:0不参与公约数和公倍数的讨论 先来讨论最大公约数: 最大公约数求法:两个数的所有公共质数相乘. 考虑三个问题. 为什么是公共的:公共代表这个数可以被两个数都整除 为什么是质数:合数一定能 ...
- C语言:欧几里得算法求最大公约数
文章目录 欧几里得算法 C语言:欧几里得算法求最大公约数 C语言:穷举法 欧几里得算法 举个例子说明欧几里得算法. 如图所示,用正方形地板砖,把这一块粉红色空地(长为xxx,宽为yyy,x>yx ...
- c语言用质因数分解法求最大公约数,分解质因数法求最大公约数(javascrip实现)
//判断是否为质数------------------------------------------------------ function isPrime(n) { for (var i = n ...
- 欧几里得算法求m,n(非负整数)的最大公约数,记为gcd(m,n);java版
基础知识:最大公约数:自行百度: 欧几里得-最大公约数算法: gcd(m,n) = gcd(n,m mod n) (m mod n 表示:m除以n后的余数) 重复此步骤,知道 m mod n等于0: ...
最新文章
- 数据结构: 线索化二叉树
- 查看TCP进程各状态连接数 IP封掉 的两个脚本
- 【Pushgateway】正则匹配,分隔逗号成数组
- 2015年10月15日学习html基础笔记
- npm -S -D的区别
- python类属性初始化_Python:如何模拟类属性初始化函数
- Alibaba Nacos配置中心功能介绍与不同命名空间、分组等配置
- 学习Jsoup(三)
- dnf服务器地址修改,修改dnf单机服务器地址
- 初学makefile
- VGL与中国海洋石油签署液化天然气购销协议;徐工汉云打造国内首个智能化剥片机组 | 能动...
- Code Complete《代码大全》读书笔记
- spring4开发SpringBatch 样例 -配置文件版
- javamail发送邮件到qq邮箱图片不能显示问题
- Mac同济大学毕业论文Latex模板环境配置
- 王者荣耀服务器ip地址配置文件,王者荣耀,关于设置的一些小技巧,知道以后你也是大神...
- python随机抽号_Python 随机从字典中抽取数据
- 微型计算机系统原理接口与EDA设计技术,微型计算机系统与接口
- 基于nodejs电影交流网站设计与实现-计算机毕业设计源码+LW文档
- R语言使用教程(三)——Rstudio添加镜像源(加快包的下载)
热门文章
- 自建CA生成证书详解
- linux命令行界面如何安装图形化界面
- bash下常用快捷键以及Linux内部帮助文档的使用
- 将字符串中连续的多个空格替换成一个空格
- sql优化-项目实战
- JavaScript服务器端高级编程(Array.indexOf()和lastIndexOf()方法)
- 客户端验证的极品--jQuery.validator
- [笔记]远传中继的实现
- python 单向链表实现快速排序_若干排序算法的Python实现方法及原理
- bagging算法_Bagging与随机森林算法及其变种