10个学生参加若干小组问题求解与分析
一个初中数学竞赛题
前一阵在程强老师拉的群里讨论一个初中数学竞赛题,已知条件为:
(1)10 个学生参加 n 个课外小组,一个小组最多 5 个学生参加
(2)每两个学生至少同时参加某一个小组 【注:原题里没有“同时”二字,存在理解上的歧义】
(3)对任意两个小组,至少可以找到两个学生,他们都不参加这两个小组
求:n 的最小值。
总体分析
如果某学生只参加一个小组,由条件(1)可知,他至多有 4 个组友;如果他参加了两个小组,那他至多有 8 个组友。因此,对任何一个学生而言,为了确保其他 9 个学生都是他的组友,他至少要参加 3 个小组,或者说他至少得有 3 个组员身份。一共 10 个学生,他们一起至少得有 30 个组员身份,而 n 个小组至多提供 5n 个组员身份,于是有 5n >= 30,即 n >= 6。
接下来只要构造出一个 n = 6 的满足上述条件的分组实例,就可得出 n 的最小值为 6 的结论。
实例构造
为方便起见,用标号 0 到 9 分别标记 10 个学生,6 个小组用G1、G2、……、G6 标识。小组内学生按标号由小到大从左到右排列,各个小组也按组内学生标号排成的5位数(最高位允许为0)由小到大从上到下排列。
比如如下的一个实例:
G1:[1,2,3,4,5]
G2:[6,7,8,9,0]
G3:[1,2,6,7,0]
G4:[0,4,5,6,8]
G5:[1,3,8,9,7]
G6:[2,3,9,5,4]
按照上述的顺序要求可以排列为如下等价的实例:
G1:[0,1,2,6,7]
G2:[0,4,5,6,8]
G3:[0,6,7,8,9]
G4:[1,2,3,4,5]
G5:[1,3,7,8,9]
G6:[2,3,4,5,9]
顺序化后,不难理解,标号 0 总是出现在前三个小组的打头位置。
假设这个实例满足上述题设条件,我们总可以通过等价调换的方式,让 G1 内的组员标号调整为 [0,1,2,3,4]。以该实例为例,3 和 4 不在 G1 里,占据对应位置的是 6 和 7,只要把该实例中出现的 6 和 3 做互换处理,再对 7 和 4 做互换处理,G1 就调整为 [0,1,2,3,4],而且不会改变对题设条件的满足情况。于是,我们可以把 G1 固定为 [0,1,2,3,4],并遵照上述的排列规则寻找满足题设的实例。
上面给出的实例并不满足题设条件,比如 G3 和 G4 的并集包含了0 到 9 所有标号,这与题设条件(3)不符。题设条件(3)的等价说法是任意两个小组,它们的并集至多包含 8 个元素(或者说它们的交集至少包含 2 个元素)。
当然这个实例同样也不满足题设的条件(2),比如 0 和 3 就没有出现在同一个小组里。
从上面的总体分析,我们知道,为满足条件(2),一个标号在 6 个小组中至少要出现 3 次,而 6 个小组至多可以提供 5*6=30 个标号位置,如果存在某个 6 个小组的满足题设条件的分组实例,那么 10 个标号中的每一个都只能在 6 个小组中正好出现 3 次。
接下来,按照上述的约定,从 G1:[0,1,2,3,4] 开始逐步构造出符合题设条件的完整分组实例。具体步骤如下:
步骤 1:
保留 0 和 1 作为重复项,替换另三项,得 G2:[0,1,5,6,7]。
步骤 2:
G3 打头的项为 0,此时 0 已经出现三次,还没有和 0 同组的 8 和 9 需要进组,即 G3:[0,a,b,8,9],a,b 是两个待定项,为使得G3 和它之上的每个组都有至少两个重复项,考虑对称性,a,b 可分别选取 1,2、2,3、2,5 三组取值。
步骤 3:
取 a,b=1,2,则前三组为:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,1,2,8,9]
按前述的顺序要求,G2 和 G3 的顺序应该互换一下,因为不影响后续分析,这里不做顺序调整。现在来构造 G4,按类似上面的分析有:
G4:[2,c,5,6,7] // c>2
由 G4 和 G1 至少有两个重复项,可知待定项 c 只能取值 3 或 4, 同样 G4 和 G3 至少有两个重复项,可知 c 只能取值 8 或 9,矛盾,说明 a,b=1,2 的情形无解。
步骤 4:
取 a,b=2,3,则前三组为:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,2,3,8,9]
G3 和 G2 的重复项只有一个,不满足题设条件(3),这种情况也不可取。
步骤 5:
取 a,b=2,5,则前三组为:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,2,5,8,9]
G3 和它之上每个组的交集都有两个元素,符合要求;继续构造 G4 如下:
G4:[1,d,e,8,9]
按 G4 分别和 G1、G2 的交集要求,可知 d 取值选自 2,3,4,e取值选自 5,6,7;再考虑到 G3 中有 2 和 5,且 G3 和 G4 有重复项 8 和 9,由对称性不妨考察 d,e=3,6,于是前四组为:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,2,5,8,9]
G4:[1,3,6,8,9]
步骤 6:
继续构造 G5,得到
G5:[2,f,g,6,7]
由 G5 与 G1 的交集要求可知待定项 f,g 中至少有一个为 3 或 4,尝试 f=3,则 3 出现了三次,由此推得 g=5,但是 4 只出现了一次,在随后的 G6 里至多也只能出现一次,由此可知 f=3 是不可取的,于是推得 f=4;而由 G5 与 G4 的交集要求可知 g 的取值为 8 或 9,由 G3、G4 里 8,9 的对称性,只需考察 g=8 即可,于是得到完整的实例如下:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,2,5,8,9]
G4:[1,3,6,8,9]
G5:[2,4,6,7,8]
G6:[3,4,5,7,9]
经验证该分组实例满足题设条件,由此可知 n 的最小值为6,问题求解完毕。
拓展分析与编程求解实现
前面的总体分析部分得出 n >= 6 的推论只用到了条件(1)和条件(2)。我们现在来考察会有哪些类型的解满足题设的条件(1)和条件(2),其中哪些类型的解还能满足条件(3)。
考察最小重复策略
我们先尝试最小重复的策略,看能不能更方便地构造出满足题设的实例:
G1:[0,1,2,3,4]
G6:[5,6,7,8,9]
G6 和 G1 没有交集,符合最小重复的策略,但是随后构造的 G2、G3、G4、G5 都无法再做到零重复了。按前述的排列顺序要求,G2 和 G3 里打头位置是 0,且 5、6、7、8、9 这五个标号要在 G2 或 G3 中至少出现一次。由对称性只需考虑如下两种情形:
【情形 1:四一分】
G1:[0,1,2,3,4]
G2:[0,5,6,7,8]
G3:[0,a,b,c,9]
G6:[5,6,7,8,9]
【情形 2:三二分】
G1:[0,1,2,3,4]
G2:[0,d,5,6,7]
G3:[0,e,f,8,9]
G6:[5,6,7,8,9]
考察情形 1
情形 1 按 G3 中的 a,b,c 的选取可能,由对称性又分为两种子情形:
【情形 1-1】
G1:[0,1,2,3,4]
G2:[0,5,6,7,8]
G3:[0,1,2,3,9] // a,b,c 全选自1,2,3,4 或 全选自 5,6,7,8,由对称性只需考虑 a=1,b=2,c=3 的情形
G6:[5,6,7,8,9]
【情形 1-2】
G1:[0,1,2,3,4]
G2:[0,5,6,7,8]
G3:[0,1,2,5,9] // a,b,c 分别从 1,2,3,4 和 5,6,7,8 中选取,由对称性只需考虑 a=1,b=2,c=5 的情形
G6:[5,6,7,8,9]
考察情形 1-1,其 G4 的打头成员标号一定是 1,因为 G1 和 G3 里已经有 1 出现,G4 里还必须出现5,6,7,8;同样,G5 里的成员也能唯一确定为 2,5,6,7,8。于是情形 1-1 对应的完整实例为:
【情形 1-1】
G1:[0,1,2,3,4]
G2:[0,5,6,7,8]
G3:[0,1,2,3,9]
G4:[1,5,6,7,8]
G5:[2,5,6,7,8]
G6:[5,6,7,8,9]
这个实例不满足题设的条件(2),比如 3 和 5 就没有出现在同一个小组中。
考察情形 1-2,会得到如下的完整实例:
【情形 1-2】
G1:[0,1,2,3,4]
G2:[0,5,6,7,8]
G3:[0,1,2,5,9]
G4:[1,g,6,7,8]
G5:[h,i,6,7,8]
G6:[5,6,7,8,9]
考察 G4 里的待定项 g,分为以下几种情形:
1、如果 g=2,那么 h=3,而 i > 3,这样 3 只出现了两次
2、如果 g=3,那么 h=2,i=3,这样 4 只出现了一次
3、如果 g>=4,那么 h = 2,i > 2,这样 3 和 4 无法保证都出现三次
由此可知,情形 1-2 的实例也无法满足题设条件(2)。
考察情形 2
【情形 2:三二分】
G1:[0,1,2,3,4]
G2:[0,d,5,6,7]
G3:[0,e,f,8,9]
G6:[5,6,7,8,9]
考察待定项 d,可以从 1,2,3,4 里取值,也可以从 8,9 里取值,由对称性分别考察 d=1 和 d=8 的子情形。
如果 d=1, 则 2,3,4 还需要和 5,6,7,8,9 同组,1 也需要和 8,9 同组,再分 e=1 和 e>1 两种情形,e=1 时由对称性只需 考察 f=2 的情形,进而可推出 G4 为 [2,j,5,6,7],这时 5,6,7 已经各自都出现了三次,但它们和 3,4 都还没有同组;再看 e>1 的情形,由对称性只需考察 e=2,f=3 的情形,进而可推出如下完整实例:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,2,3,8,9]
G4:[1,4,k,8,9]
G5:[2,3,5,6,7]
G6:[5,6,7,8,9]
因为 0 已经在前三组各出现一次,所以 G4 的打头项为 1,由于这是 1 第三次出现,为满足题设条件(2),8 和 9 也必需在 G4 中出现;此时 8 和 9 各自都出现了三次,它们还差 4 没有同组,所以 4 也必需出现在 G4 里;G4 的待定项 k 不能为 2 或 3,不然 k 值在前四组就出现了三次但依然没有和 5,6,7 同组,于是 2,3 必然出现在 G5 里,此时 2,3 已经出现三次,它们还差 5,6,7 没有同组,所以 5,6,7 必须出现在 G5 里;而且 G4 里已经有 4 了,所以 k 不能为 4,于是该实例因为 4 只出现了两次而无法满足题设条件(2)。
再来看 d=8 的情形,此时不论 e 和 f 取什么值,1,2,3,4 都还没有和 5,6,7 同组,而都需要在 G4 和 G5 中体现,不妨假设 G4=[1,2,5,6,7] ,G5=[3,4,5,6,7],于是得到如下所示的完整实例:e 的取值可以是 1 到 6,f 的取值可以是 e+1 到 7。
G1:[0,1,2,3,4]
G2:[0,5,6,7,8]
G3:[0,e,f,8,9]
G4:[1,2,5,6,7]
G5:[3,4,5,6,7]
G6:[5,6,7,8,9]
该实例中 8 已经出现三次了,但它还差 1,2,3,4 需要同组,和 8 同组的待定项只有 e 和 f,因此无法题设的条件(2)。
综上分析,可知当出现两个小组交集为空集时,不可能有满足题设条件(1)和条件(2)且 n=6 的解。所谓最小重复策略是不可取的。
考察最大重复策略
两个小组完全重复显然是不可取的,如果真的可行,那去掉一个重复小组,就得到 n=5 的结论了。
现在来考察最大有 4 个重复项的情形,看是否有满足条件的解,具体如下:
G1: [0,1,2,3,4]
G2: [0,1,2,3,5] // G2 保留 G1 的头 4 项不变,以 5 替代 4
G3: [0,6,7,8,9] // 0 出现三次,6,7,8,9 补进来
G4: [1,6,7,8,9] // 1 出现三次,6,7,8,9 补进来
G5: [2,6,7,8,9] // 2 出现三次,6,7,8,9 补进来
构造完 G5,6,7,8,9 都已经出现三次了,但是它们还没有和 3,4,5 同组。因此当两个小组里有 4 个重复项时,同样不可能有满足题设条件(1)和条件(2)且 n=6 的解。
编程求解实现
使用 C++ 语言实现的 console 程序,运行结果摘选如下:
Suppose 10 students, denoted by number 0-9, to join some groups such that
each group can contain at most 5 students and
for any 2 students, they are both in at least 1 group.
Please list all kinds of solutions with as few groups as possible.
And identify which of them can meet extra condition:
for any 2 groups, their intersection contains at least 2 students.
Step1. If student A only joins one group then he has at most 4 group-mates;
and if he joins two groups then he has at most 8 group-mates.
So for any specific student, to make sure that he has all other 9 students as his group-mates,
he must join at least 3 groups. And there are 10 of them,
for any possible group set with x groups, we have 5x >= 30, that is, x >= 6.
Step2. Now we try to list all the six-group solutions with 1st group [0,1,2,3,4].
From
G1:[0,1,2,3,4]
by swapping last 2 students, we get
G2:[0,1,2,5,6]
Try new group G3:[0,1,7,8,9]
Try new group G4:[2,3,7,8,9]
Try new group G5:[3,4,5,6,7]
Try new group G6:[4,5,6,8,9]
# Solution 1:
G1:[0,1,2,3,4]
G2:[0,1,2,5,6]
G3:[0,1,7,8,9]
G4:[2,3,7,8,9]
G5:[3,4,5,6,7]
G6:[4,5,6,8,9]
Backward to G5.
Adjusted to G5:[3,4,5,6,8]
Try new group G6:[4,5,6,7,9]
# Solution 2:
G1:[0,1,2,3,4]
G2:[0,1,2,5,6]
G3:[0,1,7,8,9]
G4:[2,3,7,8,9]
G5:[3,4,5,6,8]
G6:[4,5,6,7,9]
……
From
G1:[0,1,2,3,4]
by swapping last 3 students, we get
G2:[0,1,5,6,7]
Try new group G3:[0,1,2,8,9]
Try new group G4:[2,3,5,6,7]
Try new group G5:[3,4,5,8,9]
Try new group G6:[4,6,7,8,9]
# Solution 16:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,1,2,8,9]
G4:[2,3,5,6,7]
G5:[3,4,5,8,9]
G6:[4,6,7,8,9]
Backward to G5.
Adjusted to G5:[3,4,6,8,9]
Try new group G6:[4,5,7,8,9]
# Solution 17:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,1,2,8,9]
G4:[2,3,5,6,7]
G5:[3,4,6,8,9]
G6:[4,5,7,8,9]
……
# Solution 32:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,2,5,8,9]
G4:[1,3,6,8,9]
G5:[2,4,6,7,8]
G6:[3,4,5,7,9]
Extra condition met.
Backward to G5.
Adjusted to G5:[2,4,6,7,9]
Try new group G6:[3,4,5,7,8]
# Solution 33:
G1:[0,1,2,3,4]
G2:[0,1,5,6,7]
G3:[0,2,5,8,9]
G4:[1,3,6,8,9]
G5:[2,4,6,7,9]
G6:[3,4,5,7,8]
Extra condition met.
……
From
G1:[0,1,2,3,4]
by swapping last 4 students, we get
G2:[0,5,6,7,8]
Try new group G3:[0,1,2,5,9]
Try new group G4:[1,2,6,7,8]
Try new group G5:[3,4,5,6,7]
Student 6 is invalid in G5.
Adjusted to G5:[3,4,5,6,8]
Student 6 is invalid in G5.
Adjusted to G5:[3,4,5,6,9]
Try new group G6:[3,4,7,8,9]
# Solution 41:
G1:[0,1,2,3,4]
G2:[0,5,6,7,8]
G3:[0,1,2,5,9]
G4:[1,2,6,7,8]
G5:[3,4,5,6,9]
G6:[3,4,7,8,9]
……
In total, we found 43 solutions among which 8 solutions met extra condition.
所有的解分为三类:
第一类是从 G1:[0,1,2,3,4] 开始做交换末尾两项的操作,得到 15 个求解。
第二类是从 G1:[0,1,2,3,4] 开始做交换末尾三项的操作,得到 25 个求解,其中有 8 个满足原题的条件(3)。
第三类是从 G1:[0,1,2,3,4] 开始做交换末尾四项的操作,得到 3 个求解。
完整的运行结果以及实现源代码获取位置:
https://github.com/readalps/StuJoinGrp/