约数相关问题

<1>求所有约数

869. 试除法求约数 - AcWing题库

AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

int n;

int main()
{
    cin>>n;
    while(n--)
    {
        vector<int>v;
        int x;
        cin>>x;
        for(int i=1;i<=x/i;i++)
        {
            if(x%i==0)
            {
                v.push_back(i);
                if(i!=x/i)v.push_back(x/i);
            }
            
        }
        sort(v.begin(),v.end());
        for(auto item:v)
        cout<<item<<" ";
        cout<<endl;
    }
    return 0;
}

相关解释:

这里就枚举2到根号x的范围就可以了,最后要排个序。

注意这里要特别判断一下i和n/i是否相等,不然可能会重复。

<2>求约数的个数

870. 约数个数 - AcWing题库

AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>

using namespace std;

const int mod = 1e9+7;
int n;

int main()
{
    cin>>n;
    unordered_map<int,int>hash;
    
    while(n--)
    {
        int x;
        cin>>x;
        
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                hash[i]++;
                x/=i;
            }
        }
        if(x>1)hash[x]++;
        
    }
    long long res=1;
    for(auto item:hash)
    {
        res=(res*(item.second+1))%mod;
    }
    
    cout<<res;
    return 0;
}

相关解释:

这里使用算术基本定理(如果不知道,可以去百度),采用算术基本定理可以把所有的数分解。这题对所有的数进行分解,用什么记录呢?显然可以采用hash表来记录,如果不知道,可以看我的这篇博客STL map和unordered_map容器详解-CSDN博客。根据算法基本定理的分解式,假设分解成了p1^k1 * p2^k2 * p3*k3 * ... * pn^kn。所有这些指数k1,k2..,kn的不同选法也就构成了不同的约数,全选是最大的,与就是本身,都不选,也就是1.所以有(k1+1)*(k2+1)*..*(kn+1)种选法,也就是有这些种约数。由于可能足够大,res采用long long类型。

<3>求约数之和

871. 约数之和 - AcWing题库

AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <cmath>

using namespace std;

const int mod = 1e9+7;

int n;

int main()
{
    cin>>n;
    unordered_map<int,int>hash;
    
    while(n--)
    {
        int x;
        cin>>x;
        
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                hash[i]++;
                x/=i;
            }
        }
        if(x>1)hash[x]++;
    }
    
    long long res=1;
    
    for(auto item:hash)
    {
        long long t=1;
        int p=item.first,k=item.second;
        while(k--)
        {
            t=(t*p+1)%mod;
        }
        res=res*t%mod;
    }
    
    cout<<res;
    
    return 0;
}

相关解释:

求约数之和一样的道理,采用算术基本定理将所有这些数进行分解,使用hash表来存储底数和指数。最后的约数之和应该是(p1^0+p1^1+...+p1^k1) * (p2^0+p2^1+...+p2^k2) * ... * (pn^0+pn^1+...+pn^kn)。为什么是这样呢,因为所有从这些括号里选择一个数,这些数相乘也就构成了某个约数,所有这些数相加也就是最后的约数之和!

<4>求最大公约数

872. 最大公约数 - AcWing题库

AC‘代码:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

int n;

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

int main()
{
    cin>>n;
    while(n--)
    {
        int a,b;
        cin>>a>>b;
        cout<<gcd(a,b)<<endl;
    }
    
    return 0;
}

相关解释:

这里采用欧几里得算法(也是辗转相除法),不知道的可以百度。注意这里不需要看谁大谁小,代码也很少,非常简便。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值