CF750F New Year and Finding Roots

题目描述

这是一个交互式问题。在下文的“交互”部分,你将了解到有关输出刷新(flush)的信息。 高度为 $h$ 的新年树是一棵完美的二叉树,其顶点编号为 $1$ 到 $2^{h}-1$(顺序可任意)。在本题中,我们假设 $h$ 至少为 $2$。下图展示了一个高度为 $3$ 的新年树示例: ![](https://cdn.luogu.com.cn/upload/vjudge_pic/CF750F/07e9d5dc31cdb2b80679f5c4cff966cd8a5e5ddf.png) 北极熊们都喜欢装饰新年树,Limak 也不例外。要装饰新年树,他首先需要找到树的根节点,即度数恰好为 $2$ 的顶点(前提是 $h \geq 2$)。然而这并不容易,因为 Limak 还是只小熊,他甚至无法看清整棵树。你能帮帮他吗? 有 $t$ 组测试用例。在每一组测试用例中,你需要首先读入一个 $h$ 的值。然后,你最多可以询问 $16$ 次,询问格式为“? x”(不带引号),其中 $x$ 是 $1$ 到 $2^{h}-1$ 之间的一个整数。系统将返回 $x$ 的所有邻居的编号(详细见后文“交互”部分)。例如,对于上图所示的树,假如你询问“? 1”,会收到 $3$ 个邻居的回复:$4$、$5$ 和 $7$。你的目标是找出根的编号 $y$,再以 "! y" 的格式输出答案。只有在上一组测试用例输出答案并刷新输出后,你才能读取下一组测试用例的 $h$。 每棵树在一组测试用例内是固定不变的,在你的提问过程中不会发生改变。

输入格式

输入的第一行为一个整数 $t$($1 \leq t \leq 500$),表示测试用例的组数。 每组测试用例开始时,你需要从输入读取一个整数 $h$($2 \leq h \leq 7$),表示树的高度。你不能在没有输出前一组答案前读取下一组 $h$ 的值。

输出格式

如需查询某个顶点 $x$ 的邻居,输出 "? x"(不带引号)并换行。注意:必须在该行末输出换行符,并刷新输出,以便获得回复。 系统将回复两行。第一行为一个整数 $k$($1 \leq k \leq 3$),表示顶点 $x$ 的邻居个数。第二行包含 $k$ 个互不相同的整数 $t_1,\ldots,t_k$($1 \leq t_1 < \ldots < t_k \leq 2^{h}-1$),分别为 $x$ 的邻居的编号,升序给出。 最多允许询问 $16$ 次后,你需要给出根的编号 $y$,输出 "! y"(不带引号),换行并刷新输出。 每棵树在一组测试用例内都是固定的,在你的提问过程中不会发生改变。 如果忘记输出或者没有刷新输出,可能会因为“输出空闲限制”而被判为超时(Idleness Limit Exceeded)。 建议的刷新方法包括(只需查询/答案输出并换行): - C++:fflush(stdout); - Java:System.out.flush(); - Python:stdout.flush(); - Pascal:flush(output); - 其它语言请查阅相关文档。 若程序在任何时刻读到 $h=0$ 或 $k=0$,应立即正常退出(比如调用 exit(0))。这表明系统检测到程序的请求或输出有误,并用 0 响应,因为无法进一步处理请求。在这种情况下你会得到“Wrong Answer”判定。如果忽视 $h=0$ 或 $k=0$ 的情况,可能会导致“运行错误”、“时间/空间超限”或其它结果,因为程序可能会从已经关闭的输入流读到无效数据。 Hack。要Hack别人,请使用如下格式: 第一行包含一个整数 $t=1$(仅允许一个测试用例)。第二行包含一个整数 $h$。接下来的 $2^{h}-2$ 行,每行包含两个不同的整数 $a_i$ 和 $b_i$($1 \leq a_i, b_i \leq 2^{h}-1$),代表一条边连接了两个节点。你输出的这些边应构成一棵高度为 $h$ 的完美二叉树。 当然,参赛选手的程序不会看到这些输入。

说明/提示

在第一个样例中,树与题面给出的图一致。 在第二个样例中,有两个测试用例。第一个测试用例的树高为 $2$,共 $3$ 个顶点。第二个测试用例的树高为 $4$,共 $15$ 个顶点。你可以在下图看到这两棵树。 ![](https://cdn.luogu.com.cn/upload/vjudge_pic/CF750F/eab1b64f9987e2e235a925fc7e8de8558c5d1462.png) 由 ChatGPT 5 翻译