趣题:选取最多的子集使得任两子集恰有一个公共元素

    这里有一个有趣的问题:在集合{1, 2, …, n}中选取尽可能多的子集,使得任意两个子集的交集有且仅有一个元素。例如,当n=7时,选取{1,2,3,4}、{4,5,6,7}、{1,7}这3个集合可以满足条件。子集数还可以更大一点吗?最大是多少?给出一种构造,然后证明这个数目不可能更大了。

    当n=7时,仅仅取3个子集实在是太弱了。一种最简单的办法就可以让子集数达到6,只需取{1,2}、{1,3}、{1,4}、{1,5}、{1,6}、{1,7}即可。再仔细观察,我们发现这个结果还可以进一步改进:我们还可以再往里面添加进一个子集{1},使得这7个子集两两间仍然恰有一个公共元素。这下我们似乎不能再往里面添加任何新子集了。我们还可以做得更好吗?一个新的思路是在{1,2}、{1,3}、{1,4}、{1,5}、{1,6}、{1,7}里面加上{2,3,4,5,6,7},这同样可以让子集数达到7个,可惜我们仍然无法再往里面添加新的子集了。经过若干次尝试后,我们逐渐开始确信,在集合{1, 2, …, n}里面最多只能选出n个两两恰有一个公共元素的子集,并且构造方法无外乎上面两种。这一猜想不但与直觉相符,而且貌似也很好证明。你或许会从一些看似很直观的结论出发开始证明:“显然不可能有两个大小为1的子集”,“选取多个元素个数大于2的子集显然不划算”……但牛B就牛B在,偏偏就有这样一种子集数为n的取法,每个子集里都有不止两个元素,但仍然保证任意两个子集间恰有一个公共元素:

{1,2,3}、{1,4,5}、{1,6,7}、{2,4,7}、{3,4,6}、{3,5,7}、{2,5,6}

    这一个例子对我们的猜想足以构成威胁:子集数为n真的已经到极限了吗?证明结论有那么容易吗?看来,情况貌似比我们想象中的要复杂得多。

Read more…

(召集)你能想到的最奇妙的算法题是什么?

    昨天和老朋友BY一起吃饭时又一次不可避免地谈到了算法问题。一个有趣的话题是:提起那些最巧妙的、最离奇的牛B算法时,你想到的第一个算法题是什么?

    我第一想到的算法题是那道经典问题:n个数中有且仅有一个数出现了奇数次(其它数都出现了偶数次),如何用线性时间常数空间找出这个数。解法也只有一句话:从头到尾异或一遍,结果就是要求的那个数。该问题的加强版也异常牛B,我曾经在这里介绍过。不过,这个算法我在茶余饭后已经聊过无数次了……

    脑海中出现的另一个牛B算法题则是POJ3318:给你三个n*n的矩阵A、B、C,问你A*B是不是等于C。数据保证O(n^3)铁定超时,因此你需要想一个不用把A和B乘起来就可以验证的算法。一个基于概率的算法是随机生成一个n乘1的矩阵R,然后判断A*B*R是否等于C*R,而前者相当于A*(B*R),与后者一样都可以在O(n^2)的时间里算出来。如果算出来的结果相等,几乎可以肯定A*B和C也是相等的。

Read more…

趣题:均匀分布且和为常数的n个变量

    不知道大家有没有幻想过,数学中是否存在这样一个牛B的问题,发表出来后十几年硬是没有一个人解开;后来某人惊奇地发现,它有一个极其精妙的解答,整个解决过程只需要几句话就能说清楚,但它实在是太巧妙了,这么多年就没有任何人想到。最近我就遇到了这样的事情。3月份UyHiP的题目非常有趣,整个证明几句话就完了,但想到解法的却只有一人。
    题目描述也极其简单。对于哪些n,存在一种生成n个随机变量的算法,使得它们在0和1之间均匀分布,且它们的和是一个常数?更进一步,如果这n个变量中任意k个都相互独立,满足要求的k最大是多少(表示成关于n的函数)?

    当然,这道题目我也没想出来。答案公布前,我思考了很久,最后还是放弃了。显然n是偶数时这样的算法是存在的,例如当n=6时,只需要先独立地选取3个随机变量X_1, X_2, X_3,然后令X_4 = 1 – X_1,X_5 = 1 – X_2,X_6 = 1 – X_3即可。这可以保证6个变量之和总为3,且它们均匀地分布在[0,1]区间里。但是当n是奇数时,满足要求的算法就未必存在了。例如当n=3时,不妨让X_1和X_2随机取,X_3等于1.5 – X_1 – X_2。这种算法似乎很和谐,问题就出在X_3有可能不在0和1之间。那么,重复执行该操作直到返回一个落在[0,1]里的X_3呢?这样的话变量又不是均匀分布的了,这将让变量更容易取到中间去,因为X_1和X_2太小或太大往往算不出合法的X_3(下图是Mathematica模拟的结果)。我试图从“n个变量的和的期望值是n/2”出发,证明和为1.5的3个变量不可能均匀分布在0到1之间。不过,最终还是没有找到突破口。

Read more…

趣题:寻找策略使得总有一人猜出他背上的数

正在上虚词研究课,好友Chain发来短信说,北大BBS化学学院版上发了一道很有趣的谜题,已经上十大热门话题第三了。我也是第一次看到这个题目,和大家分享一下。

话说周一某实验室有16名同学,有一天*老师把大家叫到一起说:下周来做实验的时候,我会给你们每个人背后贴一张纸,纸上的数字从1到16都有可能,不同同学背后的数字可以重复。你们每个人可以看到别人背上的数字,但不能看到自己的数字。贴纸之后你们之间不允许进行任何形式的沟通交流。之后你们排队依次来D***,告诉我你自己背后的数字是多少;由于D***室隔音效果很好,室外的人不能听到室内的同学的说话声(更好的说法是,每个人独自在一张小纸条上写下猜测结果,这就避免了可能由排队猜数的时间和顺序带来的“交流”)。等到16名同学都猜完之后公布结果。只要你们16个人中间能有一个人猜对自己背后的数字,我会让大家都得满分;但如果你们都没有猜对自己背后的数字的话,则你们全部都要重修有机实验。那么你要怎样做才能避免挂科的命运呢?

这道题目很有意思,看答案之前不妨自己先想一下。
提示:先从两个人的情况开始想起。

Read more…

IBM Ponder This史上最难谜题:给出谜底猜谜面

    2009年2月份IBM Ponder This的谜题可能是从98年谜题月赛开办以来最难的谜题。谜题发布一个月之后仍然没有任何人答对,主办人不得不宣布延迟一个月,并再三增加提示。最终,答对此题的仍然只有7个人。很久没有看到如此精彩的谜题了,有兴趣的网友不妨试一试。
    题目非常有趣。传统的谜题是给出谜面求解谜底,但这个谜题则恰恰相反:下面这一串数字是某个问题的答案,你能猜出这个问题是什么吗?这串数字里有一个错误在哪里?

900F 80F0 8F00 80CA BE12 AA90 9400 0048 3E5B 8AC0
3400 00CB BC81 8A08 3C00 0050 BE43 00C0 3E00 A019
8059 BE13 2000 0092 BE9B 2A0B 2A00 8052 8841 04C0
3E00 840B 084B 0098 E000 8819 845A 8012 0300 0050
826F 0500 0600 846E 8264 0900 0A00 8065 0C00 0072
A054 8368 8569 4800 4400 8573 4200 4100 8349 8542
2800 2400 854D 2200 2100 9F00 E000 8888 8444 8000
0030 0DED 8222 0050 0060 8444 8222 0090 00A0 8000
00C0 0DED A000 8333 8555 4080 4040 8555 4020 4010
8333 8555 2080 2040 8555 2020 2010 8300 8500 8030
8050 0880 0840 8050 0820 0810 8030 8050 0480 0440
8050 0420 0410 8500 8030 8050 0280 0240 8050 0220
0210 8030 8050 0180 0140 8050 0120 0110 90F0 9F00
E000 8888 8444 8000 0003 0DED 8222 0005 0006 8444
8222 0009 000A 8000 000C 0DED A000 8333 8555 4008
4004 8555 4002 4001 8333 8555 2008 2004 8555 2002
2001 8300 8500 8003 8005 0808 0804 8005 0802 0801
8003 8005 0408 0404 8005 0402 0401 8500 8003 8005
0208 0204 8005 0202 0201 8003 8005 0108 0104 8005
0102 0101 9F00 8030 8050 8003 8005 0088 0084 8005
0082 0081 8003 8005 0048 0044 8005 0042 0041 8050
8003 8005 0028 0024 8005 0022 0021 8003 8005 0018
0014 8005 0012 0011 80FF 8F0F A333 8000 5000 0DED
8000 3000 0DED A333 C555 1800 1400 C555 1200 1100
8F0F A333 A555 1080 1040 A555 1020 1010 A333 A555
1008 1004 A555 1002 1001

Read more…