假设我有以下表格中的数字列表(忽略|
他们在那里形成帮助。)
00|00|xx
00|xx|00
xx|00|00
etc.
规则: XX可以是1到50之间的任何数字。没有XX值可以相同。
现在,我从符合上述格式的列表中选择一组随机数字(无重复项),并随机添加和减去它们。例如
000011 - 002400 - 230000 = -232389
如何确定原始数字以及是否仅从 -232389 添加或减去这些数字?我很难过。
谢谢!
修改
我正在寻找一个功能所以我最终不得不做一个。它只是一个概念证明函数,因此变量名称是丑陋的http://jsfiddle.net/jPW8A/。
以下实现中存在错误,并且无法在十几个方案中工作。检查下面的选定答案。
function reverse_add_subtract(num){
var nums = [];
while(num != 0){
var str = num.toString(),
L = Math.abs(num).toString().length,
MA = str.match(/^(-?[0-9]?[0-9])([0-9][0-9])([0-9][0-9])*$/);
if(MA){
var num1 = MA[1],
num2 = MA[2];
}else{
var num1 = num,
num2 = 0;
}
if(L%2)L++;
if( num2 > 50){
if(num < 0) num1--;
else num1++;
}
nums.push(num1);
var add = parseInt(num1 + Array(--L).join(0),10);
num = (num-add);
}
return nums;
}
reverse_add_subtract(-122436);
答案 0 :(得分:1)
首先,你的数学错了。您的前导零将前两个数字转换为八进制数。如果这是意图,这篇文章的其余部分并不完全适用,但可以进行调整。
11-2400-230000 = -232389
现在最后一个数字很简单,在这种情况下,它始终是前两位数,23
。删除:
-232389 + 230000 = -2389
您的第二个号码是下面的100
,在这种情况下是-2400
。你的最终号码很简单:
-2389 + 2400 = 11
答案 1 :(得分:1)
首先请注意,每个xx
组都受到[1,50]的约束。这意味着数量中[50,99]范围内的每个关联对实际上都是100 - xx
,这意味着它“从”向左“借”。 (这也意味着只有一组标准化数字和一个解决方案,如果有的话。)
所以给定输入23|23|89
(来自xx
的初始-232389
点),将其标准化 - 即,从右边开始,如果值>> 50,获得100 - 价值并向右移动100(必须平衡)。示例:(23 * 100) + 89 = 2300 * 89 = 2400 - 11 = 2389
。并且示例表明,如果它是唯一改变的东西是负面的并不重要:(-23 * 100) - 89 = -2300 - 89 = -2400 + 11 = -2389
(注意:请记住,在23组中添加1以使其成为24:在此步骤中实际上未考虑组的符号,数学只是为了显示它的示例好的!可以使用此步骤来确定符号并避免下面的额外数学,但此解决方案只是尝试在此步骤中找到候选数字。如果在此步骤之后有数字组的重复,那么那里没有解决方案;否则存在解决方案。)
归一化后的候选数字是23|24|11
(假设这是aa|bb|cc
,如下所示)。现在已知所有xx
值,只需查找e * (aa * 10000) + f * (bb * 100) + g * (cc * 1) = -232389
组合即可。值aa
,bb
,cc
从上面已知,e
,f
和g
将为1或-1,分别
解决方案警告:在水平分隔符下方提供了一种在给定确定数字(上面确定)的情况下找到加法或减法的方法。在决定是否需要额外的“提示”之前,请休息并反思上述部分。
然后可以通过利用所有xx
组在归一化之后不依赖的事实来解决这个问题。 (在每一步,尝试使下一步的输入数接近零。)
示例:
-232389 + (23 * 10000) = -2389
(e
为-1,因为它撤消了我们刚才所做的+
-2389 + (24 * 100) = 11
(同样,f
为-1)
11 - (11 * 1) = 0
(0 =胜利!g
为1,解决方案为(-1 * 23 * 10000) + (-1 * 24 * 100) + (1 * 11 * 1)
= -232389
)
快乐的家庭工作。
答案 2 :(得分:0)
噢!有人发布了一个答案,说“蛮力”,我正要回应:
function find(num){for(var i=1;i<50;i++){for(var o1=0;o1<2;o1++){for(var j=1;j<50;j++){for(var o2=0;o2<2;o2++){for(var k=1;k<50;k++){var eq;if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }}}}}}}
他们删除了它...... :(
它会在评论中出现,但这里的格式更清晰:
function find(num){
for(var i=1;i<50;i++){
for(var o1=0;o1<2;o1++){
for(var j=1;j<50;j++){
for(var o2=0;o2<2;o2++){
for(var k=1;k<50;k++){
var eq;
if(eval(eq=(i+(o1?'+':'-')+j+'00'+(o2?'+':'-')+k+'0000'))==num){ return eq; }
}
}
}
}
}
}