记得刚掌握一种编程语言时,看到数学题就会想着这道题应该怎么通过编程来计算,代码也算一种解题方法。这个时期就像是拿着锤子眼里都是钉子,总想用一种思维去解决所有的问题。
今天因为某个东西,遇到了一道题,为了不泄露题的来源,这里对题进行简单改动。
在那遥远的 S1 上林大区,有一个半径为10m的半球形水池盛满了夏季肮脏的雨水,现在想把水池清理干净,如果将雨水从上方全抽出来需要做的功为W,那么当做功 W/2 时抽了百分之多少雨水?
看到这题第一眼,就意识到这是一道典型的物理题,解题方法需要用到数学中的微积分。百度搜了一些资料,没有明确的答案,只有一些复杂的公式和答题人的臆想,我也没心思深入研究。直接找了同事来解决,同事和数学系的同事一起看了这题,想着公式和微积分怎么来解决。纸上画画也没有明显能出结果的思路。
这时,同事突然说,我们可以用计算机解决啊。
同事很快用 python 写出了解题方法,代码很简单,但是编码数十年再看到数学题时,我怎么没想到用锤子呢?
当自己刚刚学会新的东西时,这是兴趣最浓的时候,这个时候想要做各种探索,印证自己所学的能否真正用上,当熟练使用,不在新奇的时候,就失了探索欲。以为自己已经掌握了何时使用锤子、扳手、改锥,真正遇到问题又是另一回事。
继续回到这题,想要计算仍然需要直到基本的公式(不能保证完全正确)。往上抽水可以认为是对水的重力势能做功,公式为 W=FS
,其中 F 是水的重量,因为其他常量对这里计算百分比没有影响,因此可以简单认为是体积*S
,我们把半球形的水池看成一个个高度为 dH
的小圆柱组成的。通过计算所有小圆柱的体积*S
得到总功W,然后再计算当达到 W/2
时水的体积即可。水的总体积除了可以用公式直接计算外,还可以在计算总共W时一起算出来。
为了方便执行,使用 JS 来实现:
//半径
var r = 5.0
//分成100份计算
var num = 100
//每份的高度, 体积
var dH = r / num, dV = 0
//圆周率
var pi = 3.14
//总功w
var w = 0
//体积
var v = 0
//计算总功和总体积
for(var i = 1; i <= num; i++) {
//距离顶部的高度
h = i * r / num
//这一段的体积
dV = (pi * (r * r - h * h) * dH)
//当前抽取的总体积
v += dV
//当前做的总功(忽略重量等因素)
w += dV * h
}
//下面和上面算法一样,但是当达到上面 w/2 的功时停止并且计算体积的比值
var w2 = 0
var v2 = 0
var percent = 0;
for(var i = 1; i <= num; i++) {
h = i * r / num
dV = (pi * (r * r - h * h) * dH)
v2 += dV
w2 += dV * h
//当达到一半功时,此时的体积占比
if (w2 > (w / 2)) {
percent = v2 / v
break
}
}
console.log('result: ', percent)
我已经尽可能让结果没那么准确了