疯狂的谜题 Killer Puzzle

题意翻译

> 你尝试过这个可怕的问题吗? > > 1. 第一个答案是 B 的题目是( )。 > A.2 B.3 C.4 D.5 E.6 > 2. 只有一道题和它后面的那道题答案相同,这道题是( )。 > A.2 B.3 C.4 D.5 E.6 > 3. 第( )题的答案与本题相同。 > A.1 B.2 C.4 D.7 E.6 > 4. 有( )题的答案是 A。 > A.0 B.2 C.4 D.7 E.6 > 5. 与本题答案相同的问题是( )。 > A.10 B.9 C.8 D.7 E.6 > 6. 答案是 A 的问题的个数和答案是( )的问题的个数相同。 > A.B B.C C.D D.E E.以上都不是 > 7. 本题和以下问题的差(例如,A 和 B 差 1)是( )。 > A.4 B.3 C.2 D.1 E.0 > 8. 答案是元音字母的问题的个数是( )。 > A.2 B.3 C.4 D.5 E.6 > 9. 答案是辅音字母的问题的个数是( )。 > A.一个质数 B.一个阶乘数 C.一个平方数 D.一个立方数 E.5的倍数 > 10. 本问题的答案是( )。 > A.A B.B C.C D.D E.E > > **注意**: > 1. 你的答案不能自相矛盾,例如第一题不能选 B。 > 2. 需要确保你的答案是唯一正确的,例如只要问题 5 是 A,则 9 8 7 6 四题不能选 A。 > 3. 需要确保你的答案保证题目的正确性,例如若 2 3 的答案相同且 8 9 的答案相同则违背了 2 题「唯一」12 的要求。 你可以手算,但作为 OIer,用代码求解它不香吗? ## 如何编程解题 有一种方式即穷举一切可能性(毕竟 $5^{10}=9765625$,比一秒钟跑 $10^8$ 的计算机要少),并且检查是否只有你自己的代码是正确的。伪代码我们就摆在下边: ```python for all(answer_list): bad = False for testing_question in [1,2,3,4,5,6,7,8,9,10]: for testing_option in ["a","b","c","d","e"]: # 你的答案必须得是正确的 if testing_option == answer_list[testing_question] and check(testing_question, testing_option) == False: bad = True # 其他答案得是错误的 if testing_option != answer_list[testing_question] and check(testing_question, testing_option) == True: bad = True if not bad: print answer_list ``` 这里 `answer_list` 是一个字符列表,第 $i$ 个字符指代第 $i$ 个问题的答案。 不论你相不相信,满足以上问题的唯一 `answer_list` 是 `cdebeedcba`。 现在,我们要写个更通用的程序来求解类似以上问题的全部问题,而前提是先形式化的描述这些问题。 ## 形式化地描述问题 本问题使用 Lisp 方言来解决这些全部的问题。Lisp 看上去有些特别,例如 C++ 的函数 `f(a,b)` 在 Lisp 中写作 `(f a b)`,类似地 C++ 中的 `f(a,g(b,c),d)` 在 Lisp 中写作 `f(a (g b c) d)`。下面是一个描述题目的例子: ```plaintext 3. (equal (answer 3) (answer (option-value))) a. 1 b. 2 c. 4 d. 7 e. 6 ``` 这里有两个重要的内置函数: |函数|功能| |:-:|:-:| |`(answer idx)`|返回 `answer_list[idx]`(就像上文伪代码中显示的)。| |`(option-value)`|返回该题目被选中的项所代表的表达式。| 例如上面题目中 `(option-value)` 所返回的就是整数 $4$~~(对照标准答案)~~。当然选项可能不只是数字,请注意样例。 而函数 `check(testing_question,testing_option)` 可以被描述成以下这样: 1. 设置函数 `(option-value)`。 2. 计算 `(testing_question)` 的结果。 3. 如果计算中抛出异常则返回 `False`。 4. 如果这些答案是布尔类型,则返回之;否则还是返回 `False`。 有一种特殊的表达式叫做 `none-of-above`,其取决于另一些选项怎么选。本题中,最多只有一个 `none-of-above` 并且只会出现在最后一个。 ## 细节 这里有一些 Lisp 方言的细节。 + 有 $4$ 种类型的数据:整数、字符串、布尔和函数。 + 只有 $2$ 种布尔类型的数据:真或者假。当然,这里不存在布尔常量的形式化描述,既不像 `#t` 和 `#f`(于 Scheme 之中),也不像 `t` 和 `nil`(于 Common Lisp 之中)。 + 整数永远非负。 + 字符串被双引号包裹,例如 `"a string"`。 + 没有变量,此后这些被称作「标识符」,为预定义函数。 以下是一份预定义函数的列表。`!` 开头的函数可能会抛出异常而 `@` 开头的函数可能会处理异常。就像 C++ 语言一样,若一个异常被抛出,整个程序进程将终止直到异常被处理。 ### 基础函数 |函数|功能| |:-:|:-:| |`(equal a b)`|当且仅当 `a` 和 `b` 的类型和值都相等。在本问题中,你不需要比较两个函数。| |`(option-value)`|前面讨论过,这里不加赘述。| |`!(answer idx)`|讨论过,但当 `idx` 的值并非 $1 \sim n$ 的整数($n$ 即问题个数),则抛出异常。| |`!(answer-value idx)`|返回 `answer_list[idx]`,抛出异常的条件相同。| ### 谓词 谓词是一种特殊的函数,其接受一个任意类型参数并返回一个布尔值。 |函数|功能| |:-:|:-:| |`prime-p`|返回当且仅当这个参数是个正质数| |`factorial-p`|返回当且仅当这个参数是某个整数的阶乘| |`square-p`|返回当且仅当这个参数是某个整数的平方| |`cubic-p`|返回当且仅当这个参数是某个整数的立方| |`vowel-p`|返回当且仅当这个参数为字符串只有一个字母并且这个字母是元音字母| |`consonant-p`|返回当且仅当这个参数为字符串只有一个字母并且这个字母是辅音字母| ### 统计与算术 |函数|功能| |:-:|:-:| |`!@(first-question pred)`|返回第一个满足谓词 `pred` 的题目。如果不满足则抛出异常。| |`!@(last-question pred)`|功能同上,但返回的是最后一个满足谓词 `pred` 的题目。| |`!@(only-question pred)`|返回唯一满足谓词 `pred` 的题目,如果有多个满足或没有满足则抛出异常。| |`@(count-question pred)`|返回满足谓词 `pred` 的题目个数。| |`!(diff-answer idx1 idx2)`|返回题目 `idx1` 与 `idx2` 的答案的差。在发生错误(同 `answer idx` 抛出异常的条件)时抛出异常,否则返回 $0\sim m-1$ 之间的值,其中 $m$ 是题目的选项个数。| 注意在前四个函数中,若有异常被抛出时会被处理,并且该谓词不被考虑。例如,当 `answer_list="abc"` 之时,`(count-question (make-anwert-diff-next-equal 0))` 返回 $0$ 并且不抛出异常,虽然计算 `((make-answer-diff-next-equal 0)3)` 时会抛出异常。然而其他函数并不会处理异常,例如当 $n=3$ 时(即只有 $3$ 个问题时)`(factorial-p (answer-value 5))` 会抛出异常而非返回 `False`。 ### 谓词生成器 当然也有生成(更正确地说,合并)谓词的函数: |函数|功能| |:-:|:-:| |`!(make-answer-diff-next-equal num)`|返回计算 `(diff-answer idx idx+1)` 且答案等于 `num` 的谓词 `(p idx)` 并且当 `num` 不是整数的时候返回异常。| |`(make-answer-equal a)`|返回谓词 `(p idx)` 计算 `(answer idx)` 是否等于 `a`| |`(make-answer-is pred)`|返回谓词 `(p idx)` 计算 `(answer idx)` 是否满足谓词 `pred` | |`(make-answer-value-equal a)`|类似上边,计算 `(answer idx)`。| |`(make-answer-value-is pred)`|类似上边,计算 `(answer idx)`。| |`!(make-is-multiple num)`|返回计算谓词 `(p i)` 当且仅当 `num` 是整数且`i`是`num`的整数倍时返回 `True`。若 `num` 并非整数则抛出异常。| |`!(make-equal val)`|返回谓词 `(p v)`,返回值为 `(equal v val)` 的结果。当 `val` 既不是整数也不是字符串时报错。| |`(make-not pred)`|返回谓词 `(p v)` 的结果当且仅当 `(pred v)` 为 `False` 的时候返回 `True`。| |`(make-and pred1 pred2)`|返回谓词 `(p v)` 当且仅当 `(pred1 v)` 和 `(pred2 v)` 都为 `True` 时返回 `True`。请注意短路操作是不允许的。| |`(make-or pred1 pred2)`|返回谓词 `(p v)` 当且仅当 `(pred1 v)` 和 `(pred2 v)` 至少有一个为 `True` 时返回 `True`。请注意短路操作是不允许的。| 例如,`(make-is-multiple 3)` 返回谓词「某值是 $3$ 的倍数」,所以 `((make-is-multiple 3) 6)` 返回 `True` 而 `((make-is-multiple 3) 10)` 返回 `False`。而 `(make-not (make-or square-p prime-p))` 返回谓词「某值既不是平方数也不是质数」。 ## 输入格式 有最多 $50$ 个样例。每个样例以两个整数 $n$ 和 $m$,其意义已在上边解释过(再解释一遍,$n$ 为问题数目而 $m$ 为选项个数)。每个问题由 $m+1$ 行描述,即问题的表达式和选项的表达式。问题已被标号为整数 $1\sim n$ 而选项被标记为 `abcde`。选项为合法的表达式且不可能是 `option-value`(如果真是这样,那么会引起无限递归,这题也没法做了)。每个问题后缀这一个空行。 ## 输出格式 对于各个样例,输出 `Case x:` 其中 `x` 为样例的序数。后若干行是可能的答案。数据保证至少有一个答案。

题目描述

[problemUrl]: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=602&page=show_problem&problem=4404 [PDF](https://uva.onlinejudge.org/external/126/p12666.pdf) ![](https://cdn.luogu.com.cn/upload/vjudge_pic/UVA12666/43c3b0eecda2787e3b8a280b51d918e905532ecd.png)

输入输出格式

输入格式


![](https://cdn.luogu.com.cn/upload/vjudge_pic/UVA12666/7593920fdf6480dae66d00a0f60f849223710e0d.png)

输出格式


![](https://cdn.luogu.com.cn/upload/vjudge_pic/UVA12666/603ed4fce7f65806026b29207aacea263e0ffee0.png)

输入输出样例

输入样例 #1

3 3
(equal (option-value) (count-question (make-answer-equal "a")))
3
0
1
(equal (option-value) "a")
"c"
"b"
"a"
((option-value) (count-question (make-answer-equal "c")))
(make-and (make-is-multiple 2) (make-or factorial-p prime-p))
(make-not prime-p)
"none-of-above"
3 2
(equal (option-value) (answer 2))
"a"
"none-of-above"
(equal (option-value) (first-question (make-answer-diff-next-equal 0)))
1
2
((option-value) (last-question (make-answer-equal "b")))
(make-is-multiple 2)
(make-not (make-is-multiple 2))
3 2
(equal (option-value) (answer 1))
"a"
"b"
((option-value) (last-question (make-answer-diff-next-equal 0)))
(make-equal 2)
"none-of-above"
((option-value) (only-question (make-answer-equal "b")))
(make-is-multiple 2)
"none-of-above"
2 5
((option-value) (diff-answer 1 2))
factorial-p
prime-p
(make-not square-p)
(make-not cubic-p)
"none-of-above"
(equal (only-question (option-value)) 1)
(make-answer-is consonant-p)
(make-answer-is vowel-p)
(make-answer-value-equal 1)
(make-answer-value-is square-p)
"none-of-above"
2 2
(option-value)
(equal (first-question (make-answer-diffnext-equal 2)) (first-question (makeanswer-diff-next-equal 2)))
"none-of-above"
(equal (option-value) 1)
1
2

输出样例 #1

Case 1:
bcb
cca
Case 2:
aab
Case 3:
aba
Case 4:
ab
ee
Case 5:
ba