更相减损术
概念
《九章算术》是中国古代的数学专著,其中的“更相减损术”可以用来求两个数的最大公约数。
原文: 可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。
白话文: (如果需要对分数进行约分,那么)可以折半的话,就折半(也就是用2来约分)。如果不可以折半的话,那么就比较分母和分子的大小,用大数减去小数,互相减来减去,一直到减数与差相等为止,用这个相等的数字来约分。
使用步骤
第一步:任意给定两个正整数;判断它们是否都是偶数。若是,则用2约简;若不是则执行第二步。
第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数。继续这个操作,直到所得的减数和差相等为止。 则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数。 求“等数”的办法就是“更相减损术”。
代码
#include<bits/stdc++.h>
using namespace std;
int ans=1;
void gxjss(int x,int y) {
while(x != y) {
if(x > y) x -= y;
else y -= x;
}
ans *= x;
printf("gcd=%d\n", ans);
}
int main() {
int m,n;
scanf("%d %d",&m, &n);
while(m % 2 == 0 && n % 2 == 0) {
m /= 2, n /= 2;
}
gxjss(m, n);
return 0;
}
更相减损术 与 辗转相除法
辗转相除法也可以用来求两个数的最大公约数。
更相减损术和辗转相除法的主要区别在于前者所使用的运算是“减”,后者是“除”。
从算法思想上看,两者并没有本质上的区别,但是在计算过程中,如果遇到一个数很大,另一个数比较小的情况,可能要进行很多次减法才能达到一次除法的效果,从而使得算法的时间复杂度退化为O(N),其中N是原先的两个数中较大的一个。
相比之下,辗转相除法的时间复杂度稳定于O(logN)。
拉姆齐定理
友谊(friend)定理
在至少6人中,或者有3人,他们互相认识;或者有3人,他们两两互相不认识。
证明如下:
从任意一点(此处以N1为示范)可以引5条线,由鸽巢(抽屉)原理可知,至少有3条边会同色假设为红色(蓝色类似,如图一),考虑此三边的终点(N3/N4/N5)的着色情况,将此三点中的任意两点连线着红色,即可构成一个红色的K3,若此三点都着蓝色,则可构成一个蓝色K3(如图二),得证!
对于给定的两个整数m,n≥2,则一定存在一个最小整数r,使得用两种颜色(例如红蓝)无论给Kr的每条边如何染色