4
4
5
5
- [ “红色眼睛与褐色眼睛”谜题] ( #红色眼睛与褐色眼睛谜题 )
6
6
- [ 找出剩下的一个数] ( #找出剩下的一个数 )
7
- - [ 说出2199年7月2日是星期几 ] ( #说出2199年7月2日是星期几 )
7
+ - [ 说出 2199 年 7 月 2 日是星期几 ] ( #说出2199年7月2日是星期几 )
8
8
- [ 梅森素数] ( #梅森素数 )
9
9
- [ 杯中的水是否超过一半] ( #杯中的水是否超过一半 )
10
10
11
11
## “红色眼睛与褐色眼睛”谜题
12
+
12
13
从前,有个小岛上只住着和尚。有些和尚的眼睛是红色的,而另一些则是褐色的。红色眼睛的和尚受到诅咒,如果得知自己的眼睛是红色的,那么当晚 12 点必须自行了断,无一例外。
13
14
14
15
和尚间有一条不成文的规定,就是彼此不能提起对方眼睛的颜色。小岛上没有一面镜子,也没有任何可以反射自己容貌的物体。因此,没有任何一个和尚能够得知自己眼睛的颜色。出于这些原因,每个和尚都过着幸福的日子。
@@ -46,6 +47,7 @@ if ((思考时间 > 2 分钟) || (已经知道答案了吗)) {
46
47
这道题其实可以利用递归的方法。假设红眼和尚人数 N 为 10,那么我们可以适用 N 为 9 的逻辑。同理,N 为 8 或 7 时,都适用 ` N-1 ` 时的逻辑。将 ` N=1 ` ,即 “只有一个红眼和尚” 视为终止条件,即可得出最终结果。这种过程与计算机算法中函数的递归调用过程完全相同。
47
48
48
49
## 找出剩下的一个数
50
+
49
51
有一个能保存 99 个数值的数组 ` item[0], item[1],...item[98] ` 。从拥有 ` 1~100 ` 元素的集合 {1,2,3,...,100} 中,随机抽取 99 个元素保存到数组。集合中共有 100 个元素,而数组只能保存 99 个数值,所以集合中会剩下一个元素。编写程序,找出最后剩下的数。
50
52
51
53
还是先花 2 分钟想一想吧。
@@ -62,7 +64,8 @@ System.out.println("最后剩下的数是:" + res);
62
64
63
65
如果将集合的 100 个数值累加,会得到 5050。依次从 5050 减去数组中的 99 个数值,最后的数就是没能保存到数组的那个剩余数值。也许很多读者想到了与此相近的算法。即使没有得到正确答案也不用失望,因为真正应该感到失望的人是那些没能找到答案后轻易选择放弃、想要直接查看正确答案的人。
64
66
65
- ## 说出2199年7月2日是星期几
67
+ ## 说出 2199 年 7 月 2 日是星期几
68
+
66
69
先公布答案吧,2199 年 7 月 2 日是星期二。其实可以靠运气蒙一下,准确率是 1/7。要想真正求出正确答案,过程并不简单。也许有些读者会自己设计精妙算法求出正确答案,但我还是想通过约翰•康威教授的“末日”算法进行说明。
67
70
68
71
末日算法虽然不是“游戏”,但在聚会中能够引起初次见面的异性的好奇。因此,为不少“花花公子”踏入数学殿堂做出了很大贡献。例如,“美丽的女士,请告诉我您的生日,让我猜猜是星期几。” “请您随便说一个年份,我会猜出当年的情人节是星期几”。虽然听起来比较肉麻,不过这样就能一下子吸引对方的注意。
@@ -110,29 +113,30 @@ boolean isLeapYear(int year) {
110
113
6, 11.5, 17, 23, 28, 34, 39.5, 45, 51, 56, 62, 67.5, 73, 79, 84, 90, 95.5
111
114
```
112
115
113
- 就是说,1900 年“末日”是星期三,那么 1906,1917,1923... “末日”也是星期三, 11.5 表示 1911 年的“末日”是星期二(-1),而1912 年的“末日”是星期四(+1)。记住这个列表,我们就能够算出所有 20 世纪年份的“末日基准”了。
116
+ 就是说,1900 年“末日”是星期三,那么 1906,1917,1923... “末日”也是星期三, 11.5 表示 1911 年的“末日”是星期二(-1),而 1912 年的“末日”是星期四(+1)。记住这个列表,我们就能够算出所有 20 世纪年份的“末日基准”了。
114
117
115
118
如果一个美丽的姑娘说“我的生日是 1992.9.13” 时,我们可以马上说出当天的星期。既然康威列表有 90 这个数字,表示 1990 年的“末日”也是星期三,那么 1901 年(平年)“末日”是星期四(+1),1902 年(闰年)“末日”是星期六(+2),所以 9.5/9.12 也是星期六,1992.9.13 就是星期日。
116
119
117
120
不过,** 年份跨越世纪时,康威列表就会失去作用** 。
118
121
119
122
题目中问的是 2199.7.2 的星期,如果不能得知 2199 年“末日”是星期几,那么这道题很难求解。对于不同世纪的年份,没有什么特别的方法能够猜出“末日”的星期。只能将被 100 整除的年份表示为日历形式时,从中得到一些规律而已。
120
123
121
- | 日 | 一 | 二 | 三 | 四 | 五 | 六 |
122
- | ---| ---| ---| ---| ---| ---| ---|
123
- | 1599 | | 1600 | 1601 | 1602 | | |
124
- | 1700 | 1701 | 1702 | 1703 | | 1704 | 1705 |
125
- | | 1796 | 1797 | 1798 | 1799 | 1800 | 1801|
124
+ | 日 | 一 | 二 | 三 | 四 | 五 | 六 |
125
+ | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
126
+ | 1599 | | 1600 | 1601 | 1602 | | |
127
+ | 1700 | 1701 | 1702 | 1703 | | 1704 | 1705 |
128
+ | | 1796 | 1797 | 1798 | 1799 | 1800 | 1801 |
126
129
| 1897 | 1898 | 1899 | 1900 | 1901 | 1902 | 1903 |
127
- | 1999 | | | 2000 | 2001 | 2002 | 2003|
128
- | 2100 | 2101 | 2102 | 2103 | | 2104 | 2105 |
129
- | | 2196 | 2197 | 2198 | 2199 | 2200 | 2201|
130
+ | 1999 | | | 2000 | 2001 | 2002 | 2003 |
131
+ | 2100 | 2101 | 2102 | 2103 | | 2104 | 2105 |
132
+ | | 2196 | 2197 | 2198 | 2199 | 2200 | 2201 |
130
133
131
134
这道题看似简单,但其实不仅需要了解“末日”算法,还需要深入了解上述模式。上面的日历中,2199 年的“末日”是星期四,所以 2199.7.11/2199.7.4 也是星期四,所以 2199.7.2 是星期二。
132
135
133
136
感受到康威教授末日算法的精妙之处了吧。
134
137
135
138
## 梅森素数
139
+
136
140
马林•梅森是法国哲学家、修道士。16 世纪,数论领域存在着一个错误的假设,而一直被认为是事实。根据这个假设,对所有素数 p,2<sup >p</sup >-1 也是素数。将素数 2,5,7 带入,结果均为负数。
137
141
138
142
从直观角度看,对素数 p,总有 2<sup >p</sup >-1 也是素数的假设成立。不过,仅仅通过几个结果就想判断命题真伪,这在数学中是最“无知”的行为。这种代入几个变量进行的测试往往以程序能够正常运行的“晴天”作为前提条件,如果遇到“雨天”,这种只经过松散测试的程序会发生很多意想不到的问题。算法的内部逻辑应该紧凑,不给 Bug 任何可乘之机。
@@ -150,6 +154,7 @@ boolean isLeapYear(int year) {
150
154
> “如果 p 为素数时 2<sup >p</sup >-1 也是素数,那么此素数为梅森素数。”
151
155
152
156
## 杯中的水是否超过一半
157
+
153
158
空房间中有个圆柱形水杯,杯口和杯底直径相同,里面有半杯左右的水。找出方法,判断杯中水超过一半还是不到一半。空荡荡的房间中没有任何可使用的器具或工具。
154
159
155
160
答案本身非常简单,不过能够真正求解的人却寥寥无几。想问题的时候,请不要考虑房间或水的温度,以及化学反应等“不讲理”的方法。另外,不允许喝杯子里的水。
@@ -158,4 +163,4 @@ boolean isLeapYear(int year) {
158
163
159
164
即使读完题没能马上想起答案,但看到插图后能够立刻明白,也可以说很有编程的感觉。将杯子倾斜,使水面刚好到达杯口时,查看杯底的水就能得出答案了。
160
165
161
- 算法的编写与之大体相同。各位因为找不到突破口而郁闷时,甚至会怀疑给出的问题究竟有没有解。然而找到突破口后,再回首会发现,原来解决之道竟如此简单。
166
+ 算法的编写与之大体相同。各位因为找不到突破口而郁闷时,甚至会怀疑给出的问题究竟有没有解。然而找到突破口后,再回首会发现,原来解决之道竟如此简单。
0 commit comments