计算数字x的位数,其数字和等于x*m的数字和
Count the number of number x that has digit sum equal the digit sum of x*m
我试图解决以下问题,但我被卡住了。我认为这是一个动态编程问题。你能提出一些想法吗?
问题:
给定正数n(n<=18(和正数m(m<=100(。调用S(x(是x的位数之和。例如S(123(=6计数具有n个数字的整数x的数量,并且S(x(=S(x*m(
示例:
n=1,m=2结果=2
n=18,m=1结果=1000000000000000000
提前谢谢。
首先,我们需要想出一个递归公式:
从最低有效数字(LSD(到最高有效数字(MSD(,如果在计算MSD后,我们有S(x) = S(x*m)
,我们就有了一个有效的解决方案
为了验证一个数字是否是有效的解决方案,我们需要知道三件事:
- 数字S(x(的当前和是多少
- 数字S(x*m(的当前和是多少
- 当前数字是多少
因此,要回答第一个和最后一个问题很容易,我们只需要维护两个参数sum
和digit
。为了计算第二个,我们需要维护两个额外的参数,sumOfProduct
和lastRemaining
。
sumOfProduct
是电流S(x*m(lastRemaining
是(m * current digit value + lastRemaining) / 10
的结果
例如,我们有x = 123
和m = 23
-
第一位=3
sum = 3 digit = 0 sumOfProduct += (lastRemaining + 3*m) % 10 = 9 lastRemaining = (m*3 + 0)/10 = 6
-
第二位=2
sum = 5 digit = 1 sumOfProduct += (lastRemaining + 2*m) % 10 = 11 lastRemaining = (m*2 + lastRemaining)/10 = 5
-
最后一位=1
sum = 6 digit = 2 sumOfProduct += (lastRemaining + m) % 10 = 19 lastRemaining = (m + lastRemaining)/10 = 2
因为这是最后一个数字,
sumOfProduct += S(lastRemaining) = 21
。
因此,x = 123
和m = 23
不是一个有效的数字。检查x*m = 2829 -> S(x*m) = S(2829) = 21
。
因此,我们可以得到一个状态为(digit, sum, sumOfProdut, lastRemaining)
的递归公式。
因此,我们的动态编程状态是dp[18][18*9 + 1][18*9 + 1][200]
(由于m<=100,所以lastRemaining
不大于200(。
现在dp
状态超过300 MB,但如果我们使用迭代方法,它会变得更小,使用大约30 MB
这个问题可以直接计算。
根据这些文件:1、2和3(感谢@LouisRicci找到它们(,我们可以声明:
-
倍数位数和的重复周期从基数(9表示基数-10(的倒数第1位开始重复
-
S(x)
可以定义为:设a
等于x mod 9
,如果a
为零,则取9
为结果,否则取a
您可以在下面的ES6片段中播放:
IN.oninput= (_=> OUT.value= (IN.value % 9) || 9);
IN.oninput();
Input x:<br>
<input id=IN value=123><br>
S(x):<br>
<input id=OUT disabled>
-
乘法规则:
S(x * y) = S(S(x) * S(y))
。 -
S(x)
和S(x*m)
对于x=0
将始终为真,这样就没有零结果。
考虑到以上陈述,我们应该计算S(m)
:的倍数位数和的重复周期
int m = 88;
int Sm = S(m); // 7
int true_n_times_in_nine = 0;
for (int i=1; i<=9; i++) {
true_n_times_in_nine += i == S(i * Sm);
}
答案是:
result = ((pow(10, n) / 9) * true_n_times_in_nine);
由于情况为零,加一:
result++;
这是一个ES6解决方案:
S= x=> (x % 9) || 9;
TrueIn9= (m, Sm=S(m))=> [1,2,3,4,5,6,7,8,9].filter(i=> i==S(i*Sm)).length;
F= (n,m)=> ~~(eval('1e'+n)/9) * TrueIn9(m) + 1;
N.oninput=
M.oninput=
f=(_=> OUT.value= F(N.value | 0, M.value | 0));
f();
Input n: (number of digits)<br>
<input id=N value=1><br>
Input m: (multiplicative number)<br>
<input id=M value=2><br>
F(n,m):<br>
<input id=OUT disabled><br>
- C++如何计算用户输入的数字中的偶数位数
- 如何计算数组中元素的位数?(不是数组的长度),并计算其数字的总和
- 计算十进制 c++ 之后的数字
- 我可以通过取每个数字的模并取和来计算大数的模数吗?
- 在C++中编程,将 3 个数字发送到一个函数,然后计算这 3 个数字的平均函数
- 如何在向量中某个数字之后重新计算进程
- 如何计算整数的十进制数字?
- 如何使用count_if计算向量中的可变数字范围
- 如何计算整数链中使用了多少次数字?
- 如何计算给定数字在二叉树中出现的次数?
- C++在不使用pow或循环的情况下计算一个数字的幂
- 从文本文件中的每一行读取数字,并计算数字重复的次数
- 如何使用递归计算从 0 到给定数字的奇数?
- 在手臂氖中高效计算两个不同的数字
- 如何将此代码转换为两个以上的数字(计算HCF)
- 相同数字计算的怪异结果差异
- 用非常大的数字计算
- 猜数字:计算机要猜多少次才能得到正确的数字
- 从给定的数字计算所有可能的数字
- 根据存储在集合中的数字计算向量中的int