预测添加数字的数字

时间:2017-02-13 06:49:54

标签: algorithm math data-structures

有人问我这个算法问题,像往常一样,我没有回答这个问题。 :)让我们说,你有一个号码(称之为)

504

下次,你看到它,你删除了数字的最后一位数字。它变成(称之为b)

50

下次,你看到它,你删除了数字的最后一位数字。变成(称之为c)

5

现在,添加所有三个数字(a + b + c)。它变成了:

504 + 50 + 5 = 559

好的,到现在为止你可能已经很好地理解了问题陈述。

问题是:如果向您添加三个数字a + b + c(在本例中为559),您如何回到原始数字(在本例中为504)?所有解决方案都将受到赞赏。

2 个答案:

答案 0 :(得分:2)

假设您开始使用的号码看起来像xyz。也就是说,它的最后一个(十进制)数字是 z ,其倒数第二个数字是 y ,其余数字是 x 。在您的示例中,如果以504开头,则x = 5,y = 0,z = 4。原始数字的值为100x + 10y + z。

您最终得到的数字是(100x + 10y + z),(10x + y)和x的总和。这是111x + 11y + z。

请注意,我们的约束是0≤y≤9且0≤z≤9。即使它们具有最大值,我们也有11y +z≤11(9)+ 9< 111.因此我们可以反转转换:拉出111的最大倍数,然后从剩下的中拉出11的最大倍数,然后剩下的。

def transform(n):
    return n + (n/10) + (n/100)

def invert(m):
    [x, y, z] = [m/111, (m%111)/11, (m%111)%11]
    return 100*x + 10*y + z

assert transform(504) == 559 
assert invert(559) == 504

(在Python shell中尝试上述内容。请注意,即使x不是一位数字,这也有效:transform(12345)给出13702,invert(13702)给出12345,如预期的那样。)

修改:另一种解决方案,基于Paul Hankin's answer(请注意)使用m*100/111作为起点的想法。您当然可以使用该值作为粗略答案的(天花板)并尝试添加1和2以获得确切答案,但您也可以预先计算粗略答案所需的“偏移量”。

# Precomputation, to populate the "offset" dictionary
def sane_mod(a, m): return ((a % m) + m) % m
offset = {}
for y in range(10):
    for z in range(10):
        add = 10*y + 11*z
        offset[sane_mod(-add, 111)] = add

# Actual function
def invert2(m):
    rough = m * 100
    return (rough + offset[rough % 111]) / 111
assert invert2(559) == 504

答案 1 :(得分:1)

a + b + c是a + a // 10 + a // 100(其中//表示舍入除法)。这介于* 111/100 - 1.89和* 111/100之间。 (1.89,因为从// 10中丢弃的最大分数是0.9,从// 100中丢弃的最大分数是0.99,而1.89 = 0.9 + 0.99)。

所以,给定一个+ b + c,我们正在寻找整数a:

a * 111/100 - 1.89 <= a + b + c <= a * 111/100
a - 2.0979 <= (a + b + c) * 100 / 111 <= a

因此,设x = ceil((a + b + c)* 100/111),x,x + 1或x + 2中的一个必须是解。

相关问题