你可能听说过“猜单词”(hangman)这个游戏(小时候可能玩过)。你需要用尽可能少的猜测次数猜出一个单词。在每次猜测中,你给出一个字母,例如 $a$,然后你会得到该单词中所有出现 $a$ 的位置。
这可能需要相当多的猜测次数,特别是当选择了一个困难的单词时。所以,让我们稍微改变一下游戏规则。与其每次只猜一个字母,不如在一次猜测中猜一组字母。结果,你会得到所有包含所猜字母集合中任意一个字母的位置。
如果单词是 ‘hangman’,你在第一轮猜了字母 $h, z$ 和 $a$,你会得到位置 $1, 2$ 和 $6$。当然,你仍然不知道这些位置上到底是 $h, z$ 还是 $a$,但它一定是这三个字母中的一个。
你的任务是使用最多 $7$ 次猜测找到隐藏的单词(它不一定是一个标准的英语单词,可以是任何由小写英文字母组成的字符串)。
交互
这是一个交互式问题。你的程序将与一个交互器运行,交互器读取你的程序的标准输出并写入你的程序的标准输入。这种交互需要遵循特定的协议:
你的程序需要重复发送以下两种查询类型之一:
- “? $s$”,其中 $s$ 是一个由两两不同的小写字母组成的字符串。交互器会回复一个整数 $n$,随后是 $n$ 个整数 $i_1, i_2, \dots, i_n$,表示隐藏字符串中包含 $s$ 中字符的位置(从 $1$ 开始计数)。
- “! $x$”,其中 $x$ ($1 \le |x| \le 10^4$) 是一个由小写字母组成的字符串。如果 $x$ 是隐藏的字符串,交互器会回复 “correct”,否则回复 “incorrect”。在收到 “correct” 的回复后,你的程序应该终止。
所有的交互都必须以换行符结束。此外,请注意你需要刷新标准输出以确保查询被发送。例如,你可以使用:
- C++:
std::cout << std::flush - C:
fflush(stdout) - Java:
System.out.flush() - Python:
sys.stdout.flush()
隐藏单词的长度最多为 $10^4$。你最多可以使用 $7$ 次查询。
提供了一个测试工具来帮助你开发解决方案。它可以从 DOMjudge 问题概览页面下载。
一个以单词 banana 为例的猜单词游戏。
样例
样例 1
? aeiou 3 2 4 6 ? bcdfghjklmnpqrstvwxyz 3 1 3 5 ? abcd 4 1 2 4 6 ? bn 3 1 3 5 ! banana correct