用程序表示的展转相除法——求最大公约数

线段上格点的个数

  给定平面上两个格点 P 1 = ( x 1 , y 1 ) P_1=(x_1,y_1) P 2 = ( x 2 , y 2 ) P_2=(x_2,y_2) ,线段P1P2上,除P1和P2之外一共又几个格点?html

限制条件web

  • 1 0 9 x 1 , x 2 , y 1 , y 2 1 0 9 -10^9 \le x_1,x_2,y_1,y_2 \le 10^9

输入app

P1 = (1,11),P2  = (5,3)

输出svg

(2,9)、(3,7)、(四、5)

答案是 x 1 x 2 |x_1-x_2| y 1 y 2 |y_1-y_2| 的最大公约数-1(当作一个结论来记吧,我也不知道咋来的)
 
主题函数

计算最大公约数——展转相除法

g c d ( a , b ) gcd(a,b) 是计算天然数a和b的最大公约数的函数,a除以b获得的商和余数分别为p和q。由于 a = b × p q a=b\times p-q ,因此 g c d ( b , q ) gcd(b,q) 既整除a又整除b(假设 g c d ( b . q ) gcd(b.q) 求得的结果记做r,即b与q的最大公约数是r,便可表示为 b % r = = 0 , q % r = = 0 b\%r==0 , q\%r==0 ),又 a = b × p q a=b\times p-q ,因此 a ÷ r = = b × p q r b r × p q r a\div r == \frac{b\times p - q}{r} \rightarrow \frac{b}{r}\times p-\frac{q}{r} ,因此得出 g c d ( b . q ) gcd(b.q) 的结果既能整除a又能整除b,也就能整除 g c d ( a , b ) gcd(a,b) 。反之,由于 q = a b × p q = a-b\times p ,同理可证 g c d ( a , b ) gcd(a,b) 整除 g c d ( b , q ) gcd(b,q) 。所以能够知道 g c d ( a , b ) = = g c d ( b , a % b ) gcd(a,b)==gcd(b,a\%b) 。不断这样操做下去,因为gcd的第二个参数老是不断缩小的,最终会获得 g c d ( a , b ) = = g c d ( c , 0 ) gcd(a,b)==gcd(c,0) 。0和c的最大公约数是c,因此 g c d ( c , 0 ) = = c gcd(c,0)==c ,这样就计算出了 g c d ( a , b ) gcd(a,b) 。程序实现以下:
 spa

int gcd(int a,int b)
{
	if(b==0) return a;
	return gcd(b,a%b);
}
// 或者是这样
int gcd(int a,int b)
{
	return b?gcd(b,a%b):a;
}