最大公约数-数论算法

两个不同时为0的整数a,b的公约数中最大的称为其最大公约数,记作gcd(a,b).关于他的定理有很多,不一一说明.

若gcd(a,b)=1,则称a,b互质.这样的话,求互质的思路就很清晰了.

正式入题:

求最大公约数的算法有很多种,以下简单列举几种:

一:辗转取余

int gcd(int n,int m){//最大公约数 
    int i=0;
    while(m!=0){
        i=n%m;
        n=m;
        m=i;
    }
    return n;
}

二:递归

long long gcd(long long a, long long b){
    long long tmp = a % b;
    if(tmp == 0){
        return b;
    }
    return gcd(b, tmp);
}

这 两种方法都是基于欧几里得算法

EUCLID(a,b)

if b==0

return a

else return EUCLID(b,a mod b)

最后我们以一个杭电题目为例,练练手.

杭电2.1.6

 

欧几里得算法固然可以解决,但是缺点显而易见.递归吃内存,二者都会超出时间限制

2.1.6-找朋友-超时

难道就没有解决办法了吗?

欧拉函数:小于n的正整数中与n互质的数的数目.

我们首先应该要知道欧拉函数的通项公式:φ(n)=n*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…..(1-1/pn),其中pi为n的质因数.

φ(n)表示从1~n-1中有多少个数与n互素.

AC代码:

#include <iostream>

using namespace std;

int euler(int n)//欧拉函数,新朋友肯定是与会长的编号(N)互质的数 
{
    int res=n;

    for(int i=2; i*i<=n; i++)
    {
        if(n%i==0)
        {
            res=res/i*(i-1);
            while(n%i==0) n/=i;
        }
    }

    if(n>1) res=res/n*(n-1);

    return res;
}

int main(int argc, char** argv)
{
    int m;
    cin>>m;
    while(m--){
	int n;
	cin>>n;
	cout<<euler(n)<<endl;
    }
 
    return 0;
}

最后:一个gcd的应用.

最小公倍数

//求最小公倍数 
long long lcm(long long a, long long b){
    return (a * b) / gcd(a, b);
}

参考文献 算法导论第三版

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值