Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 通过数字相加预测数字_Algorithm_Math_Data Structures - Fatal编程技术网

Algorithm 通过数字相加预测数字

Algorithm 通过数字相加预测数字,algorithm,math,data-structures,Algorithm,Math,Data Structures,有人问我这个算法问题,和往常一样,我没能回答这个问题比如说,你有一个号码(叫a) 下一次,您看到它时,您将删除数字的最后一位。它变成(称为b) 下一次,您看到它时,您将删除数字的最后一位。它变成(称之为c) 现在,把这三个数字加起来(a+b+c)。它变成: 504 + 50 + 5 = 559 好的,现在你可能已经很好地理解了问题陈述 问题是:如果给你加上三个数字(在本例中为559),你怎么能回到原来的数字(在本例中为504)?所有解决方案都将不胜感激。假设您开始使用的数字看起来像xyz。也就

有人问我这个算法问题,和往常一样,我没能回答这个问题比如说,你有一个号码(叫a)

下一次,您看到它时,您将删除数字的最后一位。它变成(称为b)

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

现在,把这三个数字加起来(a+b+c)。它变成:

504 + 50 + 5 = 559
好的,现在你可能已经很好地理解了问题陈述


问题是:如果给你加上三个数字(在本例中为559),你怎么能回到原来的数字(在本例中为504)?所有解决方案都将不胜感激。

假设您开始使用的数字看起来像
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变换(n):
返回n+(n/10)+(n/100)
def反转(m):
[x,y,z]=[m/111,(m%111)/11,(m%111)%11]
返回100*x+10*y+z
断言变换(504)=559
断言反转(559)=504
(在Python shell中尝试上述操作。请注意,即使x不是一位数字,也可以这样做:
transform(12345)
给出13702,而
invert(13702)
给出12345,正如预期的那样。)


编辑:一种替代解决方案,基于(请投票)中使用
m*100/111
作为起点的想法。您当然可以使用该值的上限作为粗略答案,并尝试添加1和2以获得准确答案,但您也可以预先计算粗略答案所需的“偏移量”

#预计算,用于填充“偏移量”字典
def sane_mod(a,m):返回((a%m)+m)%m
偏移量={}
对于范围(10)内的y:
对于范围(10)内的z:
相加=10*y+11*z
偏移量[sane_mod(-add,111)]=add
#实际功能
def 2(m):
粗糙度=m*100
返回(粗略+偏移量[粗略%111])/111
断言2(559)=504

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

给定a+b+c,我们寻找整数a,这样:

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

a*111/100-1.89如果a+b+c很小(在Python3中,您必须使用
/
而不是
/
来获得整数除法。好主意,+1.if而不是(n+⌊n/10⌋+ ⌊n/100⌋) 我们去掉楼层并进行精确划分,结果是n+n/10+n/100=111n/100(例如504→504+50.4+5.04=555.44),您限制了向下舍入引入的错误。这是一个普遍而有力的想法,我应该记得经常尝试。像真正的分析师而不是组合学家一样思考。:-)回到像组合学家一样思考:当您计算m*100/111时,您与n的正确值相差了整整一倍(10y+11z)/111,其中yz是n的最后两位数字,这些数字对于0都是不同的≤Y≤9, 0≤Z≤9,因此您可以维护一个从m*100/111的小数部分到(10y+11z)/111的实际值的映射,以直接确定它是x,x+1,x+2中的哪一个,而不是尝试所有三个。
5
504 + 50 + 5 = 559
a * 111/100 - 1.89 <= a + b + c <= a * 111/100
a - 2.0979 <= (a + b + c) * 100 / 111 <= a