<1>求所有约数
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>求约数的个数
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>求约数之和
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>求最大公约数
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;
}
相关解释:
这里采用欧几里得算法(也是辗转相除法),不知道的可以百度。注意这里不需要看谁大谁小,代码也很少,非常简便。