约数

目录

一、试除法求约数

 二、 约数个数

 三、约数之和

 四、求最大公约数(欧几里得算法(辗转相除法))

1、普通做法(记)

2、STL做法(__gcd()) 


 

一、试除法求约数

给定 nn 个正整数 ai,对于每个整数 ai,请你按照从小到大的顺序输出它的所有约数。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个整数 ai。

输出格式

输出共 nn 行,其中第 i 行输出第 i 个整数 a 的所有约数。

数据范围

1≤n≤100,
2≤ai≤2×10 9

输入样例:

2
6
8

输出样例:

1 2 3 6 
1 2 4 8 
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
int n;
vector <int> get_divisorts(int n){ //求约数函数
    vector <int> res; //用了存n的所有约数
    for(int i = 1;i <= n / i;i ++){ //因为n的约数个数小于n / i
        if(n % i == 0){ //如果可以整除
            res.push_back(i); //把i压入vector
            if(i != n / i) res.push_back(n / i); //如果n不是i的平方,那n / i就是一个新的约数,把n / i压入vector
        }
    }
    sort(res.begin(),res.end()); //因为题目要求约数要从小到大排序,所以在最后需要排一次需
    return res; //返回这个数的所有约数
}
int main(){
    scanf("%d",&n); //需要求约数的数的个数
    while(n --){
        int x; //需要求约数的数
        scanf("%d",&x); //读入
        auto res = get_divisorts(x);
        //大概的讲一下auto,用来定义变量时,它表示让计算机来猜这个数的类型,在这里就表示vector <int>
        for(auto i : res) printf("%d ",i);
        //这里的for循环表示遍历res数组,i是遍历到的哪一位的数字
        printf("\n"); //记得要输出回车哦
    }
    return 0;
}

 二、 约数个数

给定 n 个正整数 ai,请你输出这些数的乘积的约数个数,答案对 109+7 取模。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个整数 ai。

输出格式

输出一个整数,表示所给正整数的乘积的约数个数,答案需对 109+7 取模。

数据范围

1≤n≤100,
1≤ai≤2×109

输入样例:

3
2
6
8

输出样例:

12

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int main()
{
    int n;
    cin>>n;
    unordered_map<int,int> prime;
    while(n--)
    {
        int x;
        cin>>x;
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                x/=i;
                prime[i]++;
            }
        }
        if(x>1)
        prime[x]++;
    }
    ll res=1;
    for(auto p : prime)
    res=res*(p.second+1)%mod;
    cout<<res<<endl;
        return  0;
}

 三、约数之和

给定 n 个正整数 ai,请你输出这些数的乘积的约数之和,答案对 109+7 取模。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个整数 ai。

输出格式

输出一个整数,表示所给正整数的乘积的约数之和,答案需对 109+7 取模。

数据范围

1≤n≤100,
1≤ai≤2×109

输入样例:

3
2
6
8

输出样例:

252

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int main()
{
    int n;
    cin>>n;
    unordered_map<int,int> prime;
    while(n--)
    {
        int x;
        cin>>x;
        for(int i=2;i<=x/i;i++)
        {
            while(x%i==0)
            {
                x/=i;
                prime[i]++;
            }
        }
        if(x>1)
        prime[x]++;
    }
    ll res=1;
    for(auto p : prime)
    {
        int f=p.first,s=p.second;
        ll t=1;
        while(s--)
        t=(t * f + 1) % mod;
        res=res * t % mod;    
    }
    cout<<res<<endl;
        return  0;
}

 四、求最大公约数(欧几里得算法(辗转相除法))

1、普通做法(记)

#include<bits/stdc++.h>
using namespace std;
/*
求两个正整数 a 和 b 的 最大公约数 d
则有 gcd(a,b) = gcd(b,a%b)
证明:
    设a%b = a - k*b 其中k = a/b(向下取整)
    若d是(a,b)的公约数 则知 d|a 且 d|b 则易知 d|a-k*b 故d也是(b,a%b) 的公约数
    若d是(b,a%b)的公约数 则知 d|b 且 d|a-k*b 则 d|a-k*b+k*b = d|a 故而d|b 故而 d也是(a,b)的公约数
    因此(a,b)的公约数集合和(b,a%b)的公约数集合相同 所以他们的最大公约数也相同 证毕#
*/
int gcd(int a, int b){
    return b ? gcd(b,a%b):a; 
}

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

2、STL做法(__gcd()) 

#include<bits/stdc++.h>
using namespace std;


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值