|
发表于 2019-3-20 17:42:17
|
显示全部楼层
本帖最后由 Croper 于 2019-3-20 18:30 编辑
这是比较接近正常数学方法的求法,速度比一个一个试真因数要快,特别是在数据较大的情况下,但是代码就相对比较复杂了
思路就是分解质因数,并根据质因数求出所有真因数,再将他们相加
应该可以写成c语言的格式,但是没有标准库真的很难受- -
- #include <iostream>
- #include <map>
- #include <vector>
- #include <math.h>
- using namespace std;
- bool IsPrime(int num);
- int prime(int n);
- bool IsPrime(int num) { //num是否是质数
- for (int i = 0; prime(i) <= sqrt(num); ++i) { //如果num不能整除所有比sqrt(num)小的质数,那么num一定是质数;
- if (num % prime(i) == 0) return false;
- }
- return true;
- }
- int prime(int n) { //获取第n个质数
- static vector<int> vec = { 2 }; //存储所有质数的vector
- while (n >= vec.size()) { //当需要获取的质数大于vector的size时,扩展vector;
- int next = vec.back();
- while (!IsPrime(++next));
- vec.push_back(next);
- }
- return vec[n];
- }
- map<int,int> RslvToPrmFctrs(int num) { //分解质因数
- if (num == 0 || num==1) return map<int,int>(); //如果要分解0,直接返回空值
- map<int, int> ret; //使用map存储分解结果,map<质因数值,质因数数量>
- int i = 0;
- while (prime(i)<=sqrt(num)) {
- if (num % prime(i) == 0) { //从小的质数开始分解,直到原数为质数为止
- ret[prime(i)]++;
- num /= prime(i);
- }
- else {
- ++i;
- }
- }
- ret[num]++;
- return ret;
- }
- int GetSumByPrmFctrs(map<int,int> PrmFctrs) { //根据质因数求所有真因数之和
- int n = 1;
- int sum = 0;
- for (auto p : PrmFctrs) { //若一个数有num1个质因数a1,num2个质因数a2..num[n]个质因数a[n],因为任意数量的值因数相乘总能得到一个因数,
- n *= p.second+1;
- }
- n--; //总的因数数量为N=(num1+1)(num2+1)..(num[n]+1),真因数数量为N-1;
- for (int i = 0; i < n; ++i) {
- int product = 1; //求每个真因数
- int a = i;
- for (auto p : PrmFctrs) {
- product *= pow(p.first, a % (p.second+1));
- a /= (p.second+1);
- }
- sum += product;
- }
- return sum;
- }
- int GetFriendNum(int num) {
- map<int, int> tmp = RslvToPrmFctrs(num); //分解质因数
- return GetSumByPrmFctrs(tmp); //根据质因数求所有真因数之和
- }
- int main() {
- vector<int> ans;
- do {
- int a;
- cin >> a;
- if (a == 0) break;
- ans.push_back(GetFriendNum(a));
- } while (true);
- cout << endl;
- for (int i : ans) {
- cout << i << endl;
- }
- system("pause");
- }
复制代码 |
|