鱼C论坛

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

题目159:因子的数根之和

[复制链接]
发表于 2016-9-14 16:17:14 | 显示全部楼层 |阅读模式

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

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

x
Digital root sums of factorisations

A composite number can be factored many different ways. For instance, not including multiplication by one, 24 can be factored in 7 distinct ways:

  24 = 2x2x2x3
  24 = 2x3x4
  24 = 2x2x6
  24 = 4x6
  24 = 3x8
  24 = 2x12
  24 = 24

Recall that the digital root of a number, in base 10, is found by adding together the digits of that number, and repeating that process until a number is arrived at that is less than 10. Thus the digital root of 467 is 8.

We shall call a Digital Root Sum (DRS) the sum of the digital roots of the individual factors of our number.
The chart below demonstrates all of the DRS values for 24.

QQ20160914-2@2x.png


The maximum Digital Root Sum of 24 is 11.
The function mdrs(n) gives the maximum Digital Root Sum of n. So mdrs(24)=11.
Find ∑mdrs(n) for 1 < n < 1,000,000.


题目:

一个合数能有很多种因子分解方式。比如说,在不包括 1 的乘积,24 可以有七种不同的分解方式如下:

    24 = 2x2x2x3
    24 = 2x3x4
    24 = 2x2x6
    24 = 4x6
    24 = 3x8
    24 = 2x12
    24 = 24

回想下,一个 10 进制数字的数根,是把它各个位的数字相加,并重复这个过程,直到这个数字小于 10。


我们把DRS叫做数字独立因子的数根之和。下表展示了 24 的所有 DRS 值。

QQ20160914-3@2x.png


24 的 DRS 值中,最大的是 11。

定义 mdrs(n) 为 n 的最大 DRS 值,因此,mdrs(24) = 11


对于 1 < n < 1,000,000,求∑mdrs(n)。

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-15 20:32:31 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2020-7-15 22:27 编辑
def getDigitalRoot(n):
    if n < 10: return n
    r = 0
    while n >= 10:
        r += n%10
        n //= 10
    r += n
    return getDigitalRoot(r)

#maximum Digital Root Sum
mdrs1M = [getDigitalRoot(x) for x in range(0,10**6+1)] #2-4s
mdrs1M[10] = 7 # 10=2*5,2+5=7  =>now [1..10] is correct
x = 10
while True:  #求[x+1, 2*x]:
    m = min(10**6, 2*x)
    # print(x+1,"-",2*x," i=[2 -", int(m**0.5),"]")
    for i in range(2, int(m**0.5)+1):
        # if x <=20: print("i=",i,"j=",max(i,(x+1)//i), (m//i))
        for j in range(max(i,(x+1)//i), (m//i)+1):
            mdrs1M[i*j] = max(mdrs1M[i*j], mdrs1M[i] + mdrs1M[j])
    x *= 2
    if m == 1000000:
        break
print("1000=",mdrs1M[1000])
print("24=",mdrs1M[24])
# 1 < n <1000,000
print(sum(mdrs1M[2:1000000])) #14489159

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +5 收起 理由
永恒的蓝色梦想 + 5 + 5 + 5 欢迎答题!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-15 22:28:02 | 显示全部楼层

欢迎答题!
你没有加代码格式,我帮你加了一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-12-1 19:49:02 | 显示全部楼层
本帖最后由 guosl 于 2020-12-2 06:37 编辑

对于一个整数n,其数字根有一个计算公式:drs(n) =  (n-1) % 9+1
对于一个整数n的最大数字根可以通过递归式:mdrs(n) = max(mdrs(a)+mdrs(b)) 对所有 a*b=n)
故本题可以应用类似筛法的方法,通过不停修改mdrs(n)的值来得到。
#include <cstdio>
#include <algorithm>
using namespace std;

const int N = 1000000;

int mdrs[N];

int main(void)
{
  for (int i = 2; i < N; ++i)
    mdrs[i] =(i - 1) % 9 + 1; //初值
  for (int i = 2; i < N; ++i) //通过类似筛法的方法不停修改mdrs
    for (int j = 2, k; (k = i*j) < N; ++j)
      mdrs[k] = max(mdrs[k], mdrs[i] + mdrs[j]);//获得更大的值
  int nSum = 0;
  for (int i = 2; i < N; ++i)
    nSum += mdrs[i];
  printf("%d\n", nSum);
  return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-7-2 21:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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