#D0637. [DAY14]通过乘积算排列

[DAY14]通过乘积算排列

这是一道交互式题目。

题目描述

33DAI 是一名顶尖的密码破译专家,刚刚截获了一段被特殊方式加密的敌方重要信息。情报显示,加密所用的密钥是一个长度为 NN 的排列 PP(一个包含从 11NN 所有整数各一次的序列)。

幸运的是,你缴获了一个奇特的查询设备,但这个设备的功能十分有限。你可以选择排列中的任意两个不同位置 iijj,设备会告诉你这两个位置上的数字的乘积,即 Pi×PjP_i \times P_j

你的任务是在不超过 NN 次查询内,完全破解出这个隐藏的排列 PP

交互格式

首先,你的程序需要从标准输入读取一个整数 NN (3N1003 \le N \le 100)。

然后,你可以开始进行查询。

要进行一次查询,请在单行('\n' 结尾)中输出 ? i j (1i,jN,ij1 \le i, j \le N, i \ne j)。然后你必须刷新输出缓冲区。之后,从标准输入读取一个整数,即 Pi×PjP_i \times P_j 的值。

当你确定了整个排列后,你需要输出最终答案。答案的格式为 ! p_1 p_2 ... p_n,即以 ! 开头,后跟一个空格,然后是排列的所有元素,用空格隔开。输出答案后,你的程序应立即终止。

在 C++ 中,cout 可以使用 cout.flush(); 刷新,或 endl 实现换行并刷新,printf 可以使用 fflush(stdout); 来强制刷新缓冲区。

4
3
12
6
? 1 2
? 1 3
? 1 4
! 3 1 4 2

样例解释

在这个例子中,隐藏的排列是 P=[3,1,4,2]P = [3, 1, 4, 2]

  • 首先程序读入 N=4N=4
  • ? 1 2 -> 查询 P1×P2=3×1=3P_1 \times P_2 = 3 \times 1 = 3。交互器返回 3
  • ? 1 3 -> 查询 P1×P3=3×4=12P_1 \times P_3 = 3 \times 4 = 12。交互器返回 12
  • ? 1 4 -> 查询 P1×P4=3×2=6P_1 \times P_4 = 3 \times 2 = 6。交互器返回 6
  • 然后程序不知道怎么回事就确定了 P=[3,1,4,2]P = [3, 1, 4, 2],输出 ! 3 1 4 2 并终止。

数据规模与约定

  • 3N1003 \le N \le 100
  • PP 是一个 11NN 的排列。
  • 你最多可以进行 NN 次查询。
  • 显然 Pi×PjP_i \times P_j 的结果不会超过 10910^9