一、欧几里得算法及其证明

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

浅谈欧几里得算法求最大公约数(GCD)的原理及简单应用的更多相关文章

  1. 浅谈Stein算法求最大公约数(GCD)的原理及简单应用

    一.Stein算法过程及其简单证明 1.一般步骤: s1:当两数均为偶数时将其同时除以2至至少一数为奇数为止,记录除掉的所有公因数2的乘积k: s2:如果仍有一数为偶数,连续除以2直至该数为奇数为止: ...

  2. 欧几里得算法求最大公约数(gcd)

    关于欧几里得算法求最大公约数算法, 代码如下: int gcd( int a , int b ) { if( b == 0 ) return a ; else gcd( b , a % b ) ; } ...

  3. 欧几里得算法求最大公约数-《Algorithms Fourth Edition》第1章

    最大公约数(Greatest Common Divisor, GCD),是指2个或N个整数共有约数中最大的一个.a,b的最大公约数记为(a, b).相对应的是最小公倍数,记为[a, b]. 在求最大公 ...

  4. 关于欧几里得算法求最大公约数,即OJ1029的参考解法

    #include <stdio.h> int main(int argc, char *argv[]) { int a,b,c; scanf("%d %d",& ...

  5. 浅谈可持久化Trie与线段树的原理以及实现(带图)

    浅谈可持久化Trie与线段树的原理以及实现 引言 当我们需要保存一个数据结构不同时间的每个版本,最朴素的方法就是每个时间都创建一个独立的数据结构,单独储存. 但是这种方法不仅每次复制新的数据结构需要时 ...

  6. [算法]求满足要求的进制(辗转相除(欧几里得算法),求最大公约数gcd)

    题目 3在十进制下满足若各位和能被3整除,则该数能被3整除. 5在十六进制下也满足此规律. 给定数字k,求多少进制(1e18进制范围内)下能满足此规律,找出一个即可,无则输出-1. 题解 写写画画能找 ...

  7. 欧几里得算法:从证明等式gcd(m, n) = gcd(n, m mod n)对每一对正整数m, n都成立说开去

    写诗或者写程序的时候,我们经常要跟欧几里得算法打交道.然而有没要考虑到为什么欧几里得算法是有效且高效的,一些偏激(好吧,请允许我用这个带有浓重个人情感色彩的词汇)的计算机科学家认为,除非程序的正确性在 ...

  8. 分解质因数法求最大公约数(javascrip实现)

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. 浅谈倍增法求解LCA

    Luogu P3379 最近公共祖先 原题展现 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入格式 第一行包含三个正整数 \(N,M,S\),分别表示树的结点个数.询问 ...

随机推荐

  1. javascript 进阶篇1 正则表达式,cookie管理,userData

    首先,什么事正则表达式呢,其实引入概念很多时候并不能帮我们明白它到底是什么,所以我先简单描述下,正则表达式,其实就是一个记录字符串规则则的字符串,等我们看完这一部分,也就能明白它到底是什么了. 基本语 ...

  2. iOS 字符串NSString 的一些常用方法

    一.字符串创建 1. NSString *str1 = [NSString new]; 2. NSString *str2 = @"字符串内容"; 二.字符串拼接 1. NSStr ...

  3. NOI2017 退役记

    OI生涯最后一篇游记写点不开心的让大家开心一下 Day -2(7.16) 上午的模拟赛奥妙重重. 下午也没怎么改题,看了一些新题,发现都不会,都看了下题解,发现大部分没看懂,好慌. 发现板子还没怎么复 ...

  4. 转载manifold learning一篇

    我恨自己不干活儿,不过也没辙. 早晚要学习流形的,今天先转一篇文章,以后找不到就尿了. 我真羡慕数学系的人,╮(╯▽╰)╭. 发信人: Kordan (K&M), 信区: AI标  题: do ...

  5. (待修莫队 没过! 抽空在检查)Dynamic len(set(a[L:R])) UVA - 12345

    #include <iostream> #include <cstdio> #include <sstream> #include <cstring> ...

  6. NEERC 15 (10/12)

    NEERC=Not Easy European Regional Contest 据说NEERC天天被搬,赶紧做了好了.在Claris和Google的帮助下做了10题,感谢cls. http://co ...

  7. 【HDU5469】Antonidas(点分治,字符串哈希)

    [HDU5469]Antonidas(点分治,字符串哈希) 题面 HDU Vjudge 题解 啊哈?什么垃圾一眼点分治+Hash判断,哈哈哈哈哈,让我来码码码. 诶,怎么WA了.改改改改改. 诶,怎么 ...

  8. BZOJ4919 [Lydsy1706月赛]大根堆 【dp + 启发式合并】

    题目链接 BZOJ4919 题解 链上的\(LIS\)维护一个数组\(f[i]\)表示长度为\(i\)的\(LIS\)最小的结尾大小 我们可以用\(multiset\)来维护这个数组,子树互不影响,启 ...

  9. 洛谷 P3942 将军令 解题报告

    P3942 将军令 题目描述 又想起了四月. 如果不是省选,大家大概不会这么轻易地分道扬镳吧? 只见一个又一个昔日的队友离开了机房. 凭君莫话封侯事,一将功成万骨枯. 梦里,小\(F\)成了一个给将军 ...

  10. 洛谷 P1436 棋盘分割 解题报告

    P1436 棋盘分割 题目描述 将一个8*8的棋盘进行如下分割:将原棋盘割下一块矩形棋盘并使剩下部分也是矩形,再将剩下的两部分中的任意一块继续如此分割,这样割了(n-1)次后,连同最后剩下的矩形棋盘共 ...