一、试除法求一个数的所有约数
约数一定是成对出现,所以枚举范围也可以优化
#include <iostream> #include <algorithm> #include <vector> using namespace std; vector<int> get_divisors(int n) { vector<int>res; for(int i=1;i<=n/i;i++) //这里枚举范围也是优化了 { if(n%i==0) { res.push_back(i); if(i!=n/i) //边界特判一下,防止这个数存了两次 { res.push_back(n/i); } } } sort(res.begin(),res.end()); //因为我们在存入res的时候是一对一对地存入的,所以最后用sort排序一下 return res; } int main() { int n=0; cin>>n; while(n--) { int ai=0; cin>>ai; auto res=get_divisors(ai); for(auto t:res) cout<<t<<' '; cout<<endl; } return 0; }
二、约数个数
·两个公式:
//两个公式首先都得先分解质因数
//两个公式都是累乘的结果
难点:已经知道分解质因数的结果了,如何用代码实现这两个公式的结果
--------代码实现的时候就每一次算新的一个因式,然后用res=res*最新的因式算最后的结果
·题目:
思路分析:
·对于给定的n个数,先求n个数的乘积的分解质因数的结果
·怎么求多个数乘积的分解质因数的结果: 对每个数都分解质因数,然后把指数累加在一起就好了
可以用unordered_map(哈希表)来存结果------unordered_map[pi]+=ai;
//重要思想:用数组下标存数,用元素的值存这个数的个数!!!
·然后再利用公式约数个数
#include <iostream> #include <algorithm> #include <cstring> #include <unordered_map> using namespace std; typedef long long LL; const int N=110; const int mod=1e9+7; int main() { int n; cin>>n; unordered_map<int,int> primes; //存储a的质因数和个数 while(n--) { int a; cin>>a; //这里用了“分解质因数”的代码知识 for(int i=2;i<=a/i;i++) //每个a都分解 所有a相乘的结果便得到了 { while(a%i==0) { a/=i; primes[i]++; } } if(a>1) primes[a]++; } //此时,哈希表primes里面就存储了所有的质因数 和 每个质因数的个数 LL res=1; for(auto p:primes)//枚举所有的质因数 { res=res*(p.second+1)%mod; //代码实现的时候就每一次算新的一个因式,然后用res=res*最新的因式算最后的结果 } cout<<res<<endl; return 0; }
三、约数之和
·公式
见上面的公式图片
·思路注意点:
代码实现约数之和的公式的时候,每一次算新的一个因式,然后用res=res*最新的因式算最后的结果。只不过每个新的因式不再是一步直接求得,也是要用小循环把每个和累加起来
#include <iostream> #include <algorithm> #include <cstring> #include <unordered_map> using namespace std; typedef long long LL; const int N=110; const int mod=1e9+7; int main() { int n; cin>>n; unordered_map<int,int> primes; //存储a的质因数和个数 while(n--) { int a; cin>>a; for(int i=2;i<=a/i;i++) //每个a都分解 所有a相乘的结果便得到了 { while(a%i==0) { a/=i; primes[i]++; } } if(a>1) primes[a]++; } //此时,哈希表primes里面就存储了所有的质因数 和 每个质因数的个数 LL res=1; for(auto p:primes)//枚举所有的质因数 { LL t=1; LL b=p.second; while(b--) { t=(t*p.first+1)%mod;//这样子t便是每一个新的因式(这里要反应过来) } res=res*t%mod; //代码实现的时候就每一次算新的一个因式,然后用res=res*最新的因式算最后的结果 } cout<<res<<endl; return 0; }
//说明:二和三的题目都涉及到了取模,代码实现的时候注意取模的处理