今天丫头问了一道算法题:
Description:Consider the sequence of digits which contains N elements in increasing order (no duplicate element). If for each 2 digits, you can insert either a "+" for addition, or a "-" for subtraction, or a " " (space) to run the digits together. None of these operators can be added in front of the digit sequence. After each interval is implemented with either "+","-" or " "(space), calculate the result of the expression, if it is zero, then print the output.
There are possible 2 kinds of inputs:
1) The char 'S' (indicate sequential) followed by a simple digit number N, indicate that you are going to handle the sequence from 1 to N, 3<=N<=15. You need to find out all the possibility with the 3 operators and have the expression with sum as zero. For example: S3
2) The char 'R' (indicate randomized) followed by a sequential with comma separated. This sequence is already ordered ascending, and you must find out all the possibility with the 3 operators and have the expression with sum as zero. For example: R3,5,7,9
Sample Input:
S7
Expected Output:
(Format of output: sequence WITH operators (including space) with correct result, if more than 1 possibilities, output each of them with semicolon separated. If no possible operator vaues found, output a "NOTFOUND". If the input is illegal, output a "ILLEGAL")
1+2-3+4-5-6+7;1+2-3-4+5+6-7;1-2 3+4+5+6+7;1-2 3-4 5+6 7;1-2+3+4-5+6-7;1-2-3-4-5+6+7
Sample Input:
R3,5,7,9,11,13
Expected Output:
(Format of output: sequence WITH operators (including space) with correct result, if more than 1 possibilities, output each of them with semicolon separated, and ORDER by " ", then "+", then "-". If no possible operator vaues found, output a "NOTFOUND". If the input is illegal, output a "ILLEGAL")
3+5+7+9-11-13
大意是任意给一组依次增大的数,之间用"+", "-", 以及" "连接,其中" "运算有优先权,然后需要输出结果为0的组合。
思考了一下,大概可以这样做(以S7,即1234为例):
1. “ ”操作符优先级高于另外两个运算符,因此可以先算,以" "的位置不同,可以(2^(n-1))种组合方式(以下以&表示" "的位置):
1 2 3 4
1&2 3 4
1 2&3 4
1&2&3 4
1 2 3&4
1&2 3&4
1 2&3&4
1&2&3&4
从实践的角度,大可抛弃最后一种(蚊子也是肉)。
2. 由步骤1,我们得到了以下组合,然后其中的每一项都可以用"+"和"-"的枚举来计算:
1 2 3 4
12 3 4
1 23 4
123 4
1 23 4
12 34
1 234
3. 我们来看另一个问题,及几个数加减为0的问题:
假设有数a b c d,
a+b+c-d和-a-b-c+d在是否为0上的结果是一样的,
是不是有点遗憾?如果是a-b-c+d就好了。那么差别在哪里?对,加上这个2a就一样了。
也就是说,当我们计算出了a+b+c-d的值z时,我们只要算一下2a-z是否为0就知道a-b-c+d的值了。也就是说,对于
+++
++-
+-+
+--
-++
-+-
--+
---
我们只需计算
+++(不可能)
++-
+-+
+--
即可,这里,我们又可以光荣的去掉第一项(蚊子也是肉2),那么这一部分的计算量为(2^m/2-1)*(m+2)=(2^(m-1)-1)*(m+2),记为f(m),f(1)=0时,意为仅有两数,由于各数均不等,所以不用计算即可确定不可能,因此计算数为0也是合理的。
注:这里m+2是指对每次计算进行的m次的加减操作以及2*a-z进行的2次操作。
4. 我们来看一下计算量吧
1 2 3 4 m=3
12 3 4 m=2
1 23 4 m=2
123 4 m=1
1 23 4 m=2
12 34 m=1
1 234 m=1
1234 m=0(不可能)
归纳一下,总计算量为:C(n-1,0)f(n-1) + C(n-1,1)*f(n-1-1) + C(n-1,2)*f(n-1-2) + ... + C(n-1, n-2)f(1)
= C(n-1,0)f(n-1) + C(n-1,1)*f(n-1-1) + C(n-1,2)*f(n-1-2) + ... + C(n-1, n-3)f(2)
因此,n=4时,运算次数为C(3,0)f(3)+C(3,1)f(2) = f(3) + 3*f(2) = (2^2-1)*(3+2) + 3*(2^1-1)*(2+2) = 3*5+3*1*4 = 27
具体的程序就不写了:P
Q.E.D