10_30 光线追踪(补充内容) 求最大公约数


前言

在查找题目相关资料时接触到一些新鲜东西,记录记录
网址:AT_agc001_b [AGC001B] Mysterious Light 题解


一、更相减损术

原文:

约分术曰:可半者半之;不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。

翻译

任意给定两个正整数:
1)判断它们是否都是偶数。若是,则用2约简;
2)以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数;
3)继续这个操作,直到所得的被减数和差相等为止。
4)第1步中约掉的若干个2的积与第2步中其中一个等数的乘积就是所求的最大公约数

原理:

刘徽:其所以相减者,皆等数之重叠,故以等数约之。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
《九章算术》更相减损术【方田篇05-06】

正常函数写法:

int gcd(int a,int b)
{
	while(a!=b)
	{
		if(a>b) 
		a-=b;
		else
		b-=a;
	}
return b;
}

递归写法

int gcd(int m,int n)
{
	if(m==n) 
	return n;
	else if(m>n) 
	return gcd(n,m-n);
	else 
	return gcd(m,n-m);
}

与辗转相除法的比较

在这里插入图片描述
1.手算方面,辗转相除法比更相减损法更简洁,因为辗转相除法使用除法,在迭代次数上要小于使用减法的更相减损法。
2.代码运行效率上来看,辗转相除法略优于更相减损法
在这里插入图片描述
可乐yue求:最大公约数不同算法的时间比较(辗转相除法,更相减损术等)

二、Stein算法

在查找更相减损术时发现的求最大公约数的新方法,它改进了辗转相除法与更相减损法

算法内容

Kemlkyo:【GCD】Stein算法(二进制算法)

原理

1.当a和b均为偶数,gcb(a,b) = 2gcb(a/2, b/2) = 2 * gcb(a>>1, b>>1)
2.当a为偶数,b为奇数,gcb(a,b) = gcb(a/2, b) = gcb(a>>1, b)
3.当a为奇数,b为偶数,gcb(a,b) = gcb(a, b/2) = gcb(a, b>>1)
4.当a和b均为奇数,利用更相减损术运算一次,gcb(a,b) = gcb(b, a-b), 此时a-b的结果必然是偶数,又可以继续进行移位运算。

代码

int Stein(int x, int y)
{
	if (x < y)
	{
		int tmp = x;
		x = y;
		y = tmp;
	}
	if ( x%y == 0)
	{
		return y;
	}
	if (x % 2 == 0 && y % 2 == 0)
	{
		return 2*Stein(x >> 1, y >> 1);
	}
	else if (x%2 == 0 && y%2 != 0)
	{
		return Stein(x >> 1, y);
	}
	else if (x % 2 != 0 && y % 2 == 0)
	{
		return Stein(x, y >> 1);
	}
	else if (x % 2 != 0 && y % 2 != 0)
	{
		return Stein(x, (x - y) >> 1);
	}

优点

虽然代码较长,但Stein算法仍有优势
欧几里得算法在处理较小数字时优势是明显的,但对于大整数时,高精度的整除和取余运算就显得非常复杂,所以Stein算法的优点就在于只需要进行移位(位运算)和减法操作,处理高精度GCD问题时相对简便;
还是这张图,可以发现,输入数字越大,Stein算法的优势越明显
在这里插入图片描述

总结

辗转相除法,更相减损法,Stein算法各有优劣,从目前我们学习的进度来看,熟练掌握辗转相除法一种即可,但同时对Stein算法的也可以了解了解,便于将来处理大数。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值