题目
- 求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。
- 限制:1 <= n <= 10000
俄罗斯农民乘法
- 又称快速乘法,对被乘数进行二进制展开后,基于加法实现乘法。由于计算机中位运算速度很快,所以效率很高。
- 算法描述:对于A * B,如果 A / 2有余数,则把B累加到最后结果中,更新A = A / 2,B = B * 2。
57 × 48 = 28 × 96 + 48 = 14 × 192 + 48 = 7 × 384 + 48 = 3 × 768 + 48 + 384 = 1 × 1536 + 48 + 384 + 768 \begin{aligned} 57 \times 48 & =28 \times 96+48 \\ & = 14 \times 192 + 48 \\ & = 7 \times 384 + 48 \\ & = 3 \times 768 + 48 + 384 \\ & = 1 \times 1536 + 48 + 384 + 768 \\ \end{aligned} 57×48=28×96+48=14×192+48=7×384+48=3×768+48+384=1×1536+48+384+768 - 这里实际上是对57进行了二进制展开
57 = 2 0 + 2 3 + 2 4 + 2 5 57 × 48 = ( 2 0 + 2 3 + 2 4 + 2 5 ) × 48 = 48 × 2 0 + 48 × 2 3 + 48 × 2 4 + 48 × 2 5 = 48 + 48 > > 1 + 48 > > 3 + 48 > > 4 + 48 > > 5 \begin{aligned} 57 & = 2^0 + 2^3 + 2^4 + 2^5 \\ 57 \times 48 & = ( 2^0 + 2^3 + 2^4 + 2^5 ) \times 48 \\ & = 48 \times 2^0 + 48 \times 2^3 + 48 \times 2^4 + 48 \times 2^5\\ & = 48 + 48>>1 + 48>>3 + 48>>4 + 48>>5 \end{aligned} 5757×48=20+23+24+25=(20+23+24+25)×48=48×20+48×23+48×24+48×25=48+48>>1+48>>3+48>>4+48>>5
function quickMultiple (A, B) {
let res = 0
while(A >= 1) {
if (A & 1) {
res += B
}
A>>1
B<<1
}
return res
}
题解
1 + 2 + . . . + = ( 1 + n ) × n 2 = ( 1 + n ) × n > > 1 1 + 2 + ... + = \frac{(1 + n) \times n}{2} = (1 + n) \times n >>1 1+2+...+=2(1+n)×n=(1+n)×n>>1
- 根据上述俄罗斯农民乘法,(1+n)*n = quickMultiple(1+n, n)
- 但是,由于题目中要求不能使用while,所以接下来对quickMultiple进行改造:
- 方法一:递归
function quickMultipleRecrution (A, B) { if (A <= 1) { return 0 } // 这里其实相当于 const res = A & 1 ? B : 0 const res = (A & 1) && B || 0 return res + quickMultipleRecrution(A>>1, B<<1) }
- 方法二:由于题目限制了n <= 1000 < 16384,二进制展开最多只有14位,所以手动模拟循环,进行14次的处理。
- 记录官方题解
function quickMultiple (A, B) { let res = 0; // 1 (A & 1) && (res += B); A >>= 1; B <<= 1; // 2 (A & 1) && (res += B); A >>= 1; B <<= 1; // 3 (A & 1) && (res += B); A >>= 1; B <<= 1; // 4 (A & 1) && (res += B); A >>= 1; B <<= 1; // 5 (A & 1) && (res += B); A >>= 1; B <<= 1; // 6 (A & 1) && (res += B); A >>= 1; B <<= 1; // 7 (A & 1) && (res += B); A >>= 1; B <<= 1; // 8 (A & 1) && (res += B); A >>= 1; B <<= 1; // 9 (A & 1) && (res += B); A >>= 1; B <<= 1; // 10 (A & 1) && (res += B); A >>= 1; B <<= 1; // 11 (A & 1) && (res += B); A >>= 1; B <<= 1; // 12 (A & 1) && (res += B); A >>= 1; B <<= 1; // 13 (A & 1) && (res += B); A >>= 1; B <<= 1; // 14 (A & 1) && (res += B); A >>= 1; B <<= 1; return res }