查找其数字平方和与给定数字相加的最小整数
Find the smallest integer whose sum of squares of digits add to the given number
示例:
输入: | 输出:
-
5 –> 12 (1^2 + 2^2 = 5(
500 -> 18888999 (1^2 + 8^2 + 8^2 + 8^2 + 9^2 + 9^2 + 9^2 = 500(
我写了一个非常简单的蛮力解决方案,但它有很大的性能问题:
#include <iostream>
using namespace std;
int main() {
int n;
bool found = true;
unsigned long int sum = 0;
cin >> n;
int i = 0;
while (found) {
++i;
if (n == 0) { //The code below doesn't work if n = 0, so we assign value to sum right away (in case n = 0)
sum = 0;
break;
}
int j = i;
while (j != 0) { //After each iteration, j's last digit gets stripped away (j /= 10), so we want to stop right when j becomes 0
sum += (j % 10) * (j % 10); //After each iteration, sum gets increased by *(last digit of j)^2*. (j % 10) gets the last digit of j
j /= 10;
}
if (sum == n) { //If we meet our problem's requirements, so that sum of j's each digit squared is equal to the given number n, loop breaks and we get our result
break;
}
sum = 0; //Otherwise, sum gets nullified and the loops starts over
}
cout << i;
return 0;
}
我正在寻找问题的快速解决方案。
使用动态规划。如果我们知道最优解的第一个数字,那么其余的将是总和的其余部分的最佳解。因此,我们可以猜测第一个数字,并对较小的目标使用缓存计算来获得最佳结果。
def digitsum(n):
best = [0]
for i in range(1, n+1):
best.append(min(int(str(d) + str(best[i - d**2]).strip('0'))
for d in range(1, 10)
if i >= d**2))
return best[n]
让我们试着解释一下大卫的解决方案。我相信他的假设是,给定一个最优解,abcd...
,n - a^2
的最佳解将是bcd...
,因此如果我们计算从1
到n
的所有解,我们可以依靠以前的解来计算小于n
的数字,因为我们尝试不同的减法。
那么我们如何解释大卫的代码呢?
(1(将数字1到n
的解按顺序放在表best
中:
for i in range(1, n+1):
best.append(...
(2( 当前查询的解决方案 i
是不同数字(d
1
和 9
之间的选择数组中的最小值,如果从i
中减去d^2
是可行的。
转换为整数的最小值...
min(int(
。的字符串 d
与先前记录在表中的n - d^2
解决方案的字符串连接(删除零的解串联(:
str(d) + str(best[i - d**2]).strip('0')
让我们修改 David 代码的最后一行,看看表格如何工作的示例:
def digitsum(n):
best = [0]
for i in range(1, n+1):
best.append(min(int(str(d) + str(best[i - d**2]).strip('0'))
for d in range(1, 10)
if i >= d**2))
return best # original line was 'return best[n]'
我们呼吁,digitsum(10)
:
=> [0, 1, 11, 111, 2, 12, 112, 1112, 22, 3, 13]
当我们到达i = 5
时,我们对d
的选择是1
和2
,因此选择数组是:
min([ int(str(1) + str(best[5 - 1])), int(str(2) + str(best[5 - 4])) ])
=> min([ int( '1' + '2' ), int( '2' + '1' ) ])
等等等等。
所以这实际上是一个众所周知的变相问题。最小硬币兑换问题,其中您将获得一笔款项并要求以最少数量的硬币付款。在这里,我们有 81、64、49、36、...、1 美分,而不是一
、镍、硬币和四分之一。显然,这是鼓励动态编程的典型示例。在动态编程中,与递归方法不同,在递归方法中,您应该从上到下,现在应该从下到上并"记住"以后需要的结果。因此。。。快多了..!
所以好的,这是我在 JS 中的方法。它可能与大卫的方法非常相似。
function getMinNumber(n){
var sls = Array(n).fill(),
sct = [], max;
sls.map((_,i,a) => { max = Math.min(9,~~Math.sqrt(i+1)),
sct = [];
while (max) sct.push(a[i-max*max] ? a[i-max*max].concat(max--)
: [max--]);
a[i] = sct.reduce((p,c) => p.length < c.length ? p : c);
});
return sls[sls.length-1].reverse().join("");
}
console.log(getMinNumber(500));
我们正在做的是从下到上生成一个名为 sls
的查找数组。这就是记忆发生的地方。然后从1
到n
开始,我们将在几个选项中映射最佳结果。例如,如果我们要查找10
的分区,我们将从 10 平方根的整数部分 3 开始,并将其保留在 max
变量中。所以 3 是其中一个数字,另一个应该是 10-3*3 = 1。然后我们查找先前求解的1
,它实际上是在 sls[0]
处[1]
的,并将 3 连接到 sls[0]
。结果是[3,1]
.一旦我们完成了 3 个,然后我们一个接一个地用一个较小的工作开始相同的工作,直到它是 1。因此,在 3 之后,我们检查 2(结果为 [2,2,1,1]
(,然后检查 1(结果为 [1,1,1,1,1,1,1,1,1,1]
(,并比较 3、2 和 1 结果的长度为最短的长度,即 [3,1]
并将其存储在 sls[9]
(又名 a[i]
(,这是我们查找数组中 10 的位置。
(编辑( 这个答案是不正确的。贪婪的方法对这个问题不起作用 - 对不起。
我将以与语言无关的方式给出我的解决方案,即算法。我还没有测试过,但我相信这应该可以解决问题,并且复杂性与输出中的位数成正比:
digitSquared(n) {
% compute the occurrences of each digit
numberOfDigits = [0 0 0 0 0 0 0 0 0]
for m from 9 to 1 {
numberOfDigits[m] = n / m*m;
n = n % m*m;
if (n==0)
exit loop;
}
% assemble the final output
output = 0
powerOfTen = 0
for m from 9 to 1 {
for i from 0 to numberOfDigits[m] {
output = output + m*10^powerOfTen
powerOfTen = powerOfTen + 1
}
}
}
- 检查输入是否不是整数或数字
- 如何找到大于整数的最小数字
- 在数字之间插入 + 或 - 符号以使其等于整数
- 为什么有时我输入一个整数,程序将第一个输入的数字打印成十进制数?
- 整数区间(或 int 数组)中每个数字的出现次数
- 当我输入字符类型的数字时,为什么我无法获得整数?
- 必须首先打印向量 v1 中最接近整数 x 的数字<int>
- 分隔整数 (C++) 的数字
- 如何优化代码以返回最接近给定整数的数字,但给定列表中不存在?
- C++:从文件中读取字符串和整数,并获得最大数字
- 如何在C ++中替换整数的前两位数字?
- 如何计算整数的十进制数字?
- 如何计算整数链中使用了多少次数字?
- 为什么这个程序接受整数和字母数字输入并打印它们? C++ 中的 std::string 也采用整数值吗?
- R 中的算术在数字上比整数更快。这是怎么回事?
- 我想使用 std::stoi 函数在 cpp 中将字符串转换为整数,因为我想在字符串中找到不同数字的总和(在下级酶中)
- 将大数字(10-12 位数字)存储在无序映射中<字符串,整数>
- 在c++中读取文件时,它如何自动将字符放入字符数组,将数字放入整数变量
- 如何从向量转换为<char>数字整数
- 如何将.txt文件中的未知数字整数保存到数组中