|
udfrog 发表于 2012-8-14 21:54 ![]()
别的思路都一样,不过最最关键的一步,问题数我怎么觉得是X*(15-C(X, 3))+C(X, 3)=15*X +(1-X)*C(X, 3) ...
#15 考试
Exam
A group of students have taken an exam. We have the following information:
.Any student answered at most 15 questions.
.Any question was answered by at least 1, at most 3 students.
.Every three students answered at least 1 common question.
How many questions can this exam contain at most?
一群学生参加考试。我们已知如下信息:
每个学生最多回答15道题。
每道题最少被一名学生回答,最多被三名学生回答。
每三名学生至少回答一道相同的问题。
这场考试最多可能包含多少问题?
---------------------
每三名学生至少回答一道相同的问题, 那么这道相同的题就只能被这三人包了,不可能再被第四人回答(条件2)。
每个学生最多回答15题,说明这个学生最多被分到15组:
假设人数为X, 针对一个特定的学生A, 所有包含了A的三人组合为C(X-1,2)。根据条件三,这些组合都必须至少回答同一道题目。各组的共同题目,在不同组合之间可能重复也可能不重复,最分散的情况(X最大化),就是A回答的15道题分散到15个组合中,即包含了A的三人组合共有15组(不一定能达到但绝对不超过15)。
假设有这么个第16组,这个组合也包含了A, 那么因为A不可能回答超过15道题,这组的共同题目必须是在A回答的15道题之中。但是这个问题必定在前面15组中被回答过,也就是说它的回答人数已经达到三人了,如果有这么个第16组, 则回答人数就超过3, 违反题意。
以上推广到任意一个学生都成立, 所以有C(X-1,2)<=15。
问题数=15*X - C(X,3)*2
公式解释:根据条件三, 每三名学生至少回答一道相同的问题,这种共同题最少有C(X,3), 它只能算到一个人头上,从另外两个人的题目中扣减,因此减去C(X,3)*2
满足的55题及其分配的例子构造:
WITH s AS (SELECT LEVEL sno FROM DUAL CONNECT BY LEVEL<=5)
,c3 AS (
SELECT qno
,DECODE(p,1,sn1,2,sn2,3,sn3) sno
FROM (SELECT ROWNUM as qno, s1.sno sn1,s2.sno sn2,s3.sno sn3
FROM s s1,s s2,s s3
WHERE s1.sno<s2.sno AND s2.sno<s3.sno
)
,(SELECT LEVEL p FROM DUAL CONNECT BY LEVEL<=3)
)
,q AS (
SELECT qno,sno FROM c3
UNION ALL
SELECT 10+(sno-1)*9+p qno,sno
FROM s
,(SELECT LEVEL p
FROM DUAL
CONNECT BY LEVEL<=9
)
)
SELECT qno,COUNT(*) FROM q GROUP BY qno;
QNO COUNT(*)
--------- ----------
1 3
22 1
25 1
30 1
34 1
42 1
43 1
51 1
54 1
6 3
11 1
13 1
28 1
29 1
44 1
47 1
2 3
14 1
20 1
21 1
26 1
31 1
4 3
5 3
24 1
32 1
46 1
53 1
8 3
17 1
23 1
35 1
37 1
38 1
48 1
55 1
33 1
40 1
41 1
45 1
50 1
52 1
3 3
7 3
18 1
27 1
36 1
49 1
9 3
10 3
12 1
15 1
16 1
19 1
39 1
分配情况:
WITH s AS (SELECT LEVEL sno FROM DUAL CONNECT BY LEVEL<=5)
,c3 AS (
SELECT qno
,DECODE(p,1,sn1,2,sn2,3,sn3) sno
FROM (SELECT ROWNUM as qno, s1.sno sn1,s2.sno sn2,s3.sno sn3
FROM s s1,s s2,s s3
WHERE s1.sno<s2.sno AND s2.sno<s3.sno
)
,(SELECT LEVEL p FROM DUAL CONNECT BY LEVEL<=3)
)
,q AS (
SELECT qno,sno FROM c3
UNION ALL
SELECT 10+(sno-1)*9+p qno,sno
FROM s
,(SELECT LEVEL p
FROM DUAL
CONNECT BY LEVEL<=9
)
)
SELECT sno,LISTAGG(qno,',') WITHIN GROUP (ORDER BY qno) qnos FROM q GROUP BY sno;
SNO
----------
QNOS
------------------------------------------------------
1
1,2,3,4,5,6,11,12,13,14,15,16,17,18,19
2
1,2,3,7,8,9,20,21,22,23,24,25,26,27,28
3
1,4,5,7,8,10,29,30,31,32,33,34,35,36,37
4
2,4,6,7,9,10,38,39,40,41,42,43,44,45,46
5
3,5,6,8,9,10,47,48,49,50,51,52,53,54,55
|
|