编程之美—4数学之趣

这一章的内容不需要写具体程序的数学问题,重点是锻炼数学分析的能力。

1、金刚坐飞机问题

金刚随机找了飞机上的一个座坐,出现了以下两种情况:

* 其它乘客都随机坐

* 其他乘客按照自己的位置坐,座位被占了的乘客随机选择位置坐

针对这两种情况,求第i个乘客做到自己原位置的概率分别是多少?

第一种情况:相当于所有人都打乱排序,共有n!种坐法,第i个乘客坐对,则其余乘客随机排,有(n-1)!种坐法,每个乘客坐对概率(n-1)!/n!=1/n

第二种情况:令P(i)表示,第i个乘客坐到座位i的概率。显然与金刚坐到谁的坐有关,P(1)是金刚坐自己的坐,P(1) = 1/N

,

再计算其他乘客的概率

核心工具是全概率公式

  第2~N个乘客的概率不容易看出,我们根据全概率公式来计算,条件为金刚坐在编号为j的座位上:

《编程之美—4数学之趣》,其中:

  • P(K=j)表示,金刚坐在座位j的概率
  • P(i|K=j)表示,在金刚坐在座位j上的情况下,第i个乘客坐在座位i的概率

显然,金刚坐在位置j的概率均等,都是
《编程之美—4数学之趣》。 条件概率P(i|K=j)的计算不太直观,我们先简单分析一下:

  1. 如果j=1,也就是说金刚居然坐在了自己的座位上,第i个乘客(其实是所有其他乘客)必然能够坐到自己座位,因此P(K=j) = 1。
  2. 如果j=i,也就是说金刚居然坐在了第i个乘客的座位上,第i个乘客肯定不能坐到自己座位,因此P(K=j) = 0。
  3. 如果j>i,也就是说,金刚坐了(第i个乘客)后面的座位,不影响前面乘客找座位,第i个乘客(其实是第2~j-1个乘客)必然能够坐到自己座位,因此P(K=j) = 1。
  4. 如果1<j<i,也就是说,金刚抢了(第i个乘客)前面的座位,肯定会影响第i个乘客(其实是第j~N个乘客)的座位。

因此,可以初步计算:

《编程之美—4数学之趣》

这时,只需要计算最后一个条件概率
《编程之美—4数学之趣》

那么,1<j<i时,P(i|K=j)到底是怎么计算的呢?下面详细推导一下j=i-1和j=i-2这两种情况,其他情况可以顺推。

如果金刚坐在了座位i-1上,第i-1个乘客可以选择座位1、i、i+1~N。每种选择的概率均等,为1/(N-i+2):

 

  1. 如果第i-1个乘客选择座位1,则第i个乘客必然能坐到自己座位,概率为1
  2. 如果第i-1个乘客选择座位i,则第i个乘客必然不能坐到自己座位,概率为0
  3. 如果第i-1个乘客选择座位i+1~N,则第i个座位必然能坐到自己座位,概率为1

根据全概率公式,有
《编程之美—4数学之趣》 如果金刚坐在了

最终结果:
《编程之美—4数学之趣》

2、瓷砖覆盖地板,能否用1*2的瓷砖覆盖N*M的地板?

分析:若N=1,m为偶数,则一定能覆盖;若N、M为奇数,则一定不能覆盖,从面积上就能证明这一点,如果其中一个为偶数,则可以转化为1的情况,可以覆盖。

扩展问题:用1*2的瓷砖覆盖2*m的地板有几种方式? 分析:若m为1,则只有1种方式,若m>1时,第一块砖可以选择横着放或者竖着放,竖着放问题转化为f(m-1),若横这放,f(m-2) 总体f(n) = f(n-1)+f(n-2)转化为非波那切数列

3、买票找零

每张球票为¥50,现有2n个人排队购票,其中n个人手持50元,n个人手持100元,假设开始售票时售票处没有零钱,问这2n个人有多少种排队方式?

分析:本题类似于括号配对问题,如果第0个符号是左括号,假设它跟第k个符号进行匹配,为满足条件,则k一定为一个奇数。假设k = 2i+1,如果第0与第k个括号配对,则城下的合法序列为f(k-1)*f(2n – k -1)即 f(2i)* f(2n-2i-2)。根据全概率公式:f(2n)= (求和i=0~n-1) f(2i)f(2n-2i-2) 需要O(n*n)的时间来计算,最后得到第推公式:f(2n)= 1/(n+1)*C(2n,n),又称catalan数。

解法二:使用0、1表示拿100和50的人,这样问题转化为求一个数列,中任意前k个位置,1的数目不小于0。定义n-1个1和n+1个0组成的序列为sigma序列,这样的序列共有C(2*n, n-1),2n个位置选n-1个。 n个1和n个0的总排列数是C(2n,n)。如果序列中存在某个k,k的前若干个数中,0比1多1个,得到一个最小的k,与后面2n-k个位置中的0和1互换,得到的新的序列为,前n-1个1 和n+1个0组成的sigma,这样就可以把一个非法的序列对应为一个唯一的sigma序列。

对任意一个sigma序列,一定存在某一k,使得k的前k项中1的个数小于0的个数,取其中最小的k,将k后2n-k项的0、1互换,新的序列就是n个1和n个0组成的非法序列,所以sigma序列和非法序列是一一对应的。非法序列数是C(2n,n-1)总共C(2n,n),则合法的是C(2n,n)-C(2n,n-1)

4、点是否在三角形内

给定二维坐标系中三角形顶点的坐标

解法一:利用三角形面积求解。给定点若在三角形内部,则与三角形各顶点组成的新的三角形的面积和一定等于原三角形面积。问题转化为求三角形面积,三角形面积可以根据三边求出 p = (a + b + c)/2,S = sqrt((p-a)*(p-b)*(p-c)*p)。 解法二:如果某点D在ABC内部,则如果沿着三角形边界逆时针走,D一定在边界左边。判断D是否在一条射线的左边,可以使用两个向量的叉积,为正则在左边,为负在右边。 解法三:重心法

上面这个方法简单易懂,速度也快,下面这个方法速度更快,只是稍微多了一点数学而已

三角形的三个点在同一个平面上,如果选中其中一个点,其他两个点不过是相对该点的位移而已,比如选择点A作为起点,那么点B相当于在AB方向移动一段距离得到,而点C相当于在AC方向移动一段距离得到。

《编程之美—4数学之趣》

所以对于平面内任意一点,都可以由如下方程来表示:

P = A + u * (C – A) + v * (B – A) // 方程1

如果系数u或v为负值,那么相当于朝相反的方向移动,即BA或CA方向。那么如果想让P位于三角形ABC内部,u和v必须满足什么条件呢?有如下三个条件:

1 u >= 0
2 v >= 0
3 u + v <= 1

几个边界情况,当u = 0且v = 0时,就是点A,当u = 0,v = 1时,就是点B,而当u = 1, v = 0时,就是点C。

整理方程1得到P – A = u(C – A) + v(B – A)。

令v0 = C – A, v1 = B – A, v2 = P – A,则v2 = u * v0 + v * v1,现在是一个方程,两个未知数,无法解出u和v,将等式两边分别点乘v0和v1的到两个等式。

1 (v2) • v0 = (u * v0 + v * v1) • v0
2 (v2) • v1 = (u * v0 + v * v1) • v1

注意到这里u和v是数,而v0,v1和v2是向量,所以可以将点积展开得到下面的式子。

1 v2 • v0 = u * (v0 • v0) + v * (v1 • v0)  // 式1
2 v2 • v1 = u * (v0 • v1) + v * (v1• v1)   // 式2

解这个方程得到:

view source
print
?

1 u = ((v1•v1)(v2•v0)-(v1•v0)(v2•v1)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))
2 v = ((v0•v0)(v2•v1)-(v0•v1)(v2•v0)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))

5、磁带文件存放优化 假设磁带上有文件长度L[0]、L[1],…,L[N-1],访问概率为:P[0],P[1],…,P[N],问怎样安排他们在磁带上的顺序最好。磁带只能顺序访问

分析:根据期望,访问文件的平均长度为E(L) =  (P(0)*L[0]  + … P(i) * (L[0]+L[1]+L[I])+…p(N-1)*(L(0)+L[1]+…+L[N-1])
如果访问概率相等,则当然是长度最小的排在前面最好, 可以按照顺序进行排序。
如果文件长度一样,则将访问概率最高的排在前面最好。
考虑使用P/L的关系,例如两个文件长度为10 和 6,访问概率为0.4和0.6, a在b前面,平均长度为(10*0.4+0.6*(10+6))最后结果为13.6 。b如果在a前面,则最后的平均长度为10.
最后的结果是p/l按照由大到小进行存储,则小的会排在最前面

6、桶中取黑白球

桶里有黑白球各100个,每次从桶里拿两个球,如果两个位同色,就再放入一个黑球,如果两个异色,再放入一个白球,则最后桶里只剩下一个黑球的概率是多少?

分析:根据如上规则:取出两个黑球,放入一个黑球,实际上等于拿出一个黑球
取出两个白球,放入一个黑球,白球少了两个,黑球增加一个
取出两个异色的球,则放入一个白球,实际等于拿出一个黑球

可以看出,白球数目只能不变或者同时变两个,最后当白球数目为偶数时,则最后一定剩一个黑球,当白球数目为奇数时,一定剩的是白球,题目中白球为偶数,则最后结果一定是黑球。

7、蚂蚁爬杆

有个27厘米的木杆,在第3、7、11、17、23厘米的位置各有一个蚂蚁,同一个时间内,木杆上只能过一只蚂蚁,蚂蚁相遇会调头,蚂蚁的初始朝向是任意的。问编写程序实现蚂蚁离开木杆的最短时间和最长时间。

分析:两只蚂蚁相遇就调头走,可以看做是独立的,两只蚂蚁还是按照原来的方向。因此只要计算每一只蚂蚁按照原方向走的距离即可。优化,由于蚂蚁离开的时间与它在木杆上的位置有关,因此可以先求出离两边最近的点和离中点最近的一点的朝向。

扩展:1、 第i只蚂蚁什么时候走出木杆?

                  根据题意,如果有m只蚂蚁向左走,n-m只一开始向右走,则一定有m只从左边落下,n-m只从右边落下。又因为蚂蚁相遇后会调头,则不会有两只蚂蚁交换位置,则一定是左边的m只蚂蚁从左边落下,右边的n-m只蚂蚁从右边落下。如果i<m,则i一定是左边落下的第i只蚂蚁只要计算第i个向左走的蚂蚁走了多长时间,就能得到蚂蚁走出木杆的时间

2、 所有蚂蚁从一开始到离开木杆,碰撞了多少次

其实就是找蚂蚁之间相交了多少次

3、第k次碰撞发生在哪个时间?哪个位置?哪两只蚂蚁

4、哪只蚂蚁的碰撞次数最多?

根据1得出,左边的M只蚂蚁一定从左边掉下,如果 i<M,i左边有r个向右走的蚂蚁,则i一定要与这r个蚂蚁碰撞一次,才能让r个蚂蚁向左落下,i自己也要跟右边的蚂蚁碰撞r次,才能仍然向左,则若i一开始向左,需要2r次碰撞,如果向右是 2r+1

8、三角形测试用例

输入三角形的边长,判断谁否能构成一个三角形,是什么样的三角形?(等边、直交、锐角、钝角、等腰)

函数声明:byte GetTriangleType(int, int , int)

如何用一个byte来表示各种输出情况,如果编写功能测试

分析:注意包括:正常输入情况下、非法输入情况下、边界值附近、换位枚举等情况。一般给出15~20个案例比较合适

9、数独知多少

给出一个数独,问有多少种不同的数独解答?其中有多少种是相互独立的?

如果用一个简单的字符串表示各种数独,如何保证在1对一的基础上,让字符串长度最短?、

分析:不独立是指两个数独可以通过将两个数字进行交换得到,如果不考虑是否独立,一个空的数组有N个解答,其中独立的解答有N/(9!)

10、数字哑谜和回文

一个数包括了1~9这9个数字,这个9位数的前n位都能被n整除,

有这样一个乘法算式:人过大佛寺*我 = 寺佛大过人,这里面每个字都代表一个不同的字,能找到这样的数字么?

问题一:通过运用剪枝减少计算次数,可以从2位开始判断,2位只能为2、4、6、8,第三位,必须满足(a+b+c)能被3整除,第四位满足cd能被4整除,d可选2、4、6、8,以此类推。

    原文作者:moonboat0331
    原文地址: https://blog.csdn.net/moonboat0331/article/details/9958901
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞