鱼C论坛

 找回密码
 立即注册
查看: 2720|回复: 3

题目88:考察不同大小集合的最小积和数

[复制链接]
发表于 2016-8-10 18:03:38 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Product-sum numbers

A natural number, N, that can be written as the sum and product of a given set of at least two natural numbers,   QQ20160810-1@2x.png is called a product-sum number: QQ20160810-2@2x.png

For example, 6 = 1 + 2 + 3 = 1 × 2 × 3.

For a given set of size, k, we shall call the smallest N with this property a minimal product-sum number. The minimal product-sum numbers for sets of size, k = 2, 3, 4, 5, and 6 are as follows.

QQ20160810-3@2x.png


Hence for 2≤k≤6, the sum of all the minimal product-sum numbers is 4+6+8+12 = 30; note that 8 is only counted once in the sum.

In fact, as the complete set of minimal product-sum numbers for 2≤k≤12 is {4, 6, 8, 12, 15, 16}, the sum is 61.

What is the sum of all the minimal product-sum numbers for 2≤k≤12000?


题目:

一个自然数N如果能写成一个两个元素以上的集合, QQ20160810-1@2x.png ,中元素的积与和的话,该数字被称为积和数: QQ20160810-2@2x.png

例如:6 = 1 + 2 + 3 = 1 × 2 × 3.

对于一个大小为 k 的集合,我们将最小的具有该性质的数字 N 成为一个最小积和数。k = 2, 3, 4, 5, 6 的集合的最小积和数如下:

QQ20160810-3@2x.png


因此对于 2≤k≤6, 所有最小积和数的总和为 4+6+8+12 = 30;注意 8 在求和时只计算一次。

事实上对于 2≤k≤12,所有最小积和数的集合是 {4, 6, 8, 12, 15, 16},其和为 61。

对于 2≤k≤12000,所有最小积和数的和是多少?

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-10-17 16:31:55 | 显示全部楼层
这题的思路是运用分解质因数,先把一个数分解成所有质因数。然后用1来补足不足的位数,如果补完后的和与原来相等,则找到积合数。
sum of minimal product-sum numbers: 7587457
max. number is 12200
[Finished in 0.8s]
  1. import math

  2. def factorize(n):
  3.         f = []
  4.         d = 2
  5.         bound = math.sqrt(n)
  6.         while d <= bound and n > 1:
  7.                 if n % d == 0:
  8.                         f.append(d)
  9.                         n = n / d
  10.                 else:
  11.                         d = d + 1
  12.         if n > 1:
  13.                 f.append(n)
  14.         return f

  15. def factorizations(n):
  16.         f = factorize(n)
  17.         sol = set()
  18.         sol.add(tuple())
  19.         for p in f:
  20.                 prev = sol
  21.                 sol = set()
  22.                 for pf in prev:
  23.                         sol.add(tuple(sorted(pf + (p, ))))
  24.                         t = list(pf)
  25.                         for i in range(len(t)):
  26.                                 t[i] *= p
  27.                                 sol.add(tuple(sorted(t)))
  28.                                 t[i] /= p
  29.         return sol

  30. kmax = 12000
  31. mpsn = [ None ] * (kmax + 1)
  32. rem = kmax - 1

  33. n = 2
  34. while rem > 0:
  35.         for nf in factorizations(n):
  36.                 no = n - sum(nf) # number of ones
  37.                 k = no + len(nf)
  38.                 if k < 2 or k > kmax:
  39.                         continue
  40.                 elif mpsn[k] is None:
  41.                         mpsn[k] = n
  42.                         rem -= 1
  43.                
  44.         n += 1
  45.        
  46. mpsns = set(mpsn[2:])
  47. print 'sum of minimal product-sum numbers:', sum(mpsns)
  48. print 'max. number is', n - 1
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-6-4 15:05:12 | 显示全部楼层
  1. mem = []
  2. used = set()
  3. k = set(range(2, 12001))
  4. for n in range(9999999999999999):
  5.   mem.append(set())
  6.   if len(k) == 0:
  7.     break
  8.   for p in range(2, 999999999999999999999):
  9.     if p * p > n:
  10.       break
  11.     if n % p != 0:
  12.       continue
  13.     d = n // p
  14.     for i in mem[d]:
  15.       mem[n].add(i + n - p - d + 1)
  16.   mem[n].add(1)
  17.   for i in mem[n]:
  18.     if i in k:
  19.       k.remove(i)
  20.       used.add(n)

  21. print(sum(used))
复制代码

https://github.com/devinizz/project_euler/blob/master/page02/88.py
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-16 23:06:50 | 显示全部楼层
  1. /*
  2. 答案:7587456
  3. 耗时:0.671572秒
  4. */
  5. #include <iostream>
  6. #include <algorithm>
  7. #include <vector>
  8. #include <cmath>
  9. #include <cstring>
  10. using namespace std;

  11. const int N = 12000;//欲求的范围
  12. const int M = 24000;//计算的范围

  13. int k[N + 1];//记录要求的结果
  14. int fp[M];//fp[i]记录i的最小素因数
  15. int pc[M];//记录i的素因数个数

  16. /*
  17. 对x进行分解为nc个因数的乘积
  18. int nc 分解的因数个数
  19. int x 要被分解的数
  20. int nS 前面已经分解的因数和
  21. vector<int> &v 记录整个分解的因数之和
  22. */
  23. void dfs(int nc, int x, int nS, vector<int> &v)//递归计算分解
  24. {
  25.   if (nc == 1)//分解结束
  26.   {
  27.     v.push_back(nS + x);
  28.     return;
  29.   }
  30.   if (fp[x] == x)//x是素数无法分解
  31.     return;
  32.   for (int i = fp[x]; i <= (int)sqrt((double)x); ++i)//枚举x的可能因数
  33.   {
  34.     if (x%i == 0)
  35.       dfs(nc - 1, x / i, nS + i, v);//继续下去
  36.   }
  37. }

  38. int main(void)
  39. {
  40.   memset(k, -1, sizeof(k));//将k都预置为-1
  41.   //应用筛法求每个数的最小素数数
  42.   for (int i = 1; i < M; ++i)
  43.     fp[i] = i;
  44.   for (int i = 2; i <= (int)sqrt((double)M); ++i)
  45.   {
  46.     if (fp[i] < i)
  47.       continue;
  48.     for (int j = i*i; j < M; j += i)
  49.       fp[j] = min(fp[j], i);
  50.   }
  51.   //计算每个数的素因数个数
  52.   for (int i = 2; i < M; ++i)
  53.   {
  54.     int x = i;
  55.     while (x > 1)
  56.     {
  57.       int y = fp[x];
  58.       x /= y;
  59.       ++pc[i];
  60.     }
  61.   }
  62.   //计算k
  63.   for (int i = 4; i < M; ++i)
  64.   {
  65.     if (fp[i] == i)//素数肯定不是和积数
  66.       continue;
  67.     for (int j = 2; j <= pc[i]; ++j)
  68.     {
  69.       vector<int> v;
  70.       dfs(j, i, 0, v);//对i进行长度为j的因数分解
  71.       for (auto itr = v.begin(); itr != v.end(); ++itr)//对不同的分解计算k
  72.       {
  73.         int u = i - *itr;//计算积与和的差,补上上这些1就成了和积数
  74.         if (u >= 0 && u <= N)
  75.         {
  76.           u += j;//加上分解的长度
  77.           if (k[u] < 0)
  78.             k[u] = i;
  79.           else
  80.             k[u] = min(k[u], i);
  81.         }
  82.       }
  83.     }
  84.   }
  85.   //排序和去重
  86.   sort(k, k + N + 1);
  87.   auto itr_end = unique(k, k + N + 1);
  88.   //求和
  89.   long long nSum = 0;
  90.   for (auto itr = k; itr != itr_end; ++itr)
  91.     nSum += *itr;
  92.   cout << nSum << endl;
  93.   return 0;
  94. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-11 18:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表