杂题几道

1. 在斗地主中,求地主(20张牌)拿到至少一个炸弹的概率。

2. 假设有两个瓶子,分别设为 A 瓶和 B 瓶,其中 A 瓶装了大半瓶的白酒, B 瓶装了整整一满瓶红酒,现在将B瓶中的红酒往A瓶里倒,直到 A 瓶装满为止。将 A 瓶中的酒搅拌均匀,然后再回倒入 B 瓶,直到 B 瓶重新装满。这时问,是 A 瓶中的红酒多,还是 B 瓶中的白酒多。假设在上一步中 A 瓶并未搅拌均匀,情况又如何。

3. 一个 8*8 的矩阵 A ,设下标范围是[0,7][0,7],其元素满足关系 Aij = i * 10 + j ,也就是说 Aij 即是 10 进制形式的 ij 。现在给定任意一个自然数 n,判断它是否为 A 的上三角元素。这很简单,你可以这样写:

int d = n / 10;
int r = n % 10;
return < 8 && d <= r

 但是上面用了两次比较操作。你能用仅一次比较操作就完成这个判断么?

答案:

1. 先计算一个炸弹也没拿到的概率:考虑点数(从 2 到 A)相同的四张牌,选择其中一张有 C(4, 1) = 4 种拿法,选两张有 C(4, 2) = 6 种拿法,选三张有 C(4, 3) = 4 种拿法, 不选有 C(4, 0) = 1 种拿法。而对于大小王来说,选其中 1 张有两种拿法。根据上述信息可以列出生成函数:

G(x) = (x^0 + 4 x^1 + 6 x^2 + 4 x^3)^13 * (x^0 + 2 x^1)

那么在 G(x) 展开式中,x^n 的系数(这里用G[n]来表示)就是在一幅牌中拿不含炸弹的 n 张牌的拿法总数。地主是 20 张牌, 于是我们可以算出地主至少有一个炸弹的概率为:

1 - G[20] / C(54, 20) = 0.303686.

另外,如果要计算地主拿到至少一个非王炸的概率,可以令 G(x) = (x^0 + 4 x^1 + 6 x^2 + 4 x^3)^13 * (x^0 + 2 x^1 + x^2) 即可,得出的概率为:0.189823.

2. 比较有迷惑性的一道题,这里只需要注意到A瓶中的酒的体积,在那一系列动作的前后,是不变的,于是倒出去的白酒跟拿回来的红酒肯定是一样多。

3. 可用这个表达式来判断:n / 11 + n % 11 < 8.  一个简单的推导如下:

设 n = 11 p + q,那么有(p + q) < 8.  于是:

n / 10 = (10p + p + q) / 10 = p + (p+q) / 10 < p + 8 / 10 = p

n % 10 = (10p + p + q) % 10 = ( p + q ) % 10 < 8;

于是令 d = n / 10 = p, r = n % 10 = p + q, 有 d <= r, r < 8,就跟前面贴出的代码一样了。

来源:

1. 来自Top Language上的一次讨论,当时也有人给出了动态规划的解法,但这事实上与生成函数解法是等价的,只是相当于用动态规划来计算G[20]而已。

2. 来自<蚁迹寻踪及其他数学探索>

3. 该 trickery 来自<TAOCP>。

原文地址:https://www.cnblogs.com/atyuwen/p/somePuzzles.html