如何检查是否可以安排5个给定数字和数学运算(+, - ,*)来得到23的结果?
例如:
1 1 1 1 1 - 不可能
1 2 3 4 5 - 可能
规格:
所有操作都具有相同的优先级,并从左到右执行(不在数学上正确的顺序)。
答案 0 :(得分:1)
虽然您可以使用蛮力来尝试每种可能的组合,但我还是建议一个更优雅的解决方案:
最后一位数字以及乘法是关键。如果结果(23)不能被最后一位整除,则最后一个运算符不能为“ *”。然后,您可以对结果+-最后一位进行相同的尝试,因为最后一位可以加或减。以这种方式向后迭代应该节省很多迭代。
伪代码示例:
var digits = [1, 2, 3, 4, 5];
var expected = 23;
var combinatoric = function(digits, expected) {
var result = false;
var digit = digits[digits.length -1];
var nDigits = digits.removeLast();
// If we are at the last digit...
if(nDigits.isEmpty() && Math.abs(digit) == Math.abs(expected)) {
//Last digit must be added or substracted, as its the starting digit.
result = true;
} else if(!nDigits.isEmpty()) {
//Only if divisible is "*" an option.
if(expected % digit == 0) {
if(combinatoric(nDigits, expected / digit) {
result = true;
}
}
// "+" and "-" are always options.
if(combinatoric(nDigits, expected - digit) {
result = true;
}
if(combinatoric(nDigits, expected + digit) {
result = true;
}
}
return result;
}
这种方法至少可以节省几次迭代,因为如果它仍然无法解析为自然数,则不要尝试相乘。而且,通过向后移动,可以将计算结果递归,因为修改后的预期结果将传递给每个迭代。