luogu#P12090. [RMI 2019] 秘密排列 / Secret Permutation

    ID: 36402 远端评测题 2000ms 256MiB 尝试: 0 已通过: 0 难度: (无) 上传者: 标签>2019交互题Special JudgeRMI(罗马尼亚)

[RMI 2019] 秘密排列 / Secret Permutation

题目背景

不要引入 permutation.h

你需要在文件头添加

int query(vector<int>);
void answer(vector<int>);

我们在附件中提供了 Sample Grader。

题目描述

这是一道交互题。本题中,交互库是非自适应的。

有一个隐藏的 1n1\sim n 的排列 p1pnp_1\sim p_n

你可以进行如下的询问:

询问 给定 1n1\sim n 的排列 v1vnv_1\sim v_n。交互库会返回

$$\sum_{1\le i\le n-1} \left|p_{v_i}-p_{v_{i+1}}\right| $$

目标是,找到与 pp 等价的任意一个排列 pp'

定义:我们说排列 pppp' 等价,当且仅当它们无法通过询问区分。亦即,无论 vv 取什么,询问的答案都相同。

实现细节

你不需要,也不应该实现 main 函数。

你需要在文件头添加

int query(vector<int>);
void answer(vector<int>);

你应该实现如下的函数:

void solve(int n);

每个测试点中仅调用一次,表示要找出长度为 nn 的排列 1n1\sim n

你可以调用如下的函数:

int query(vector<int> v);
  • 发起一次询问。
  • v[i1]=viv[i-1]=v_i1in\forall 1\le i\le n)是一个 1n1\sim n 的排列。
  • 返回 $\displaystyle \sum_{1\le i\le n-1} \left|p_{v_i}-p_{v_{i+1}}\right|$。
void answer(vector<int> p);
  • 报告排列 pp
  • p[i1]=pip[i-1]=p_i1in\forall 1\le i\le n)表示你找到的排列。
  • 调用此函数后,程序将立刻终止。

注意:参数中的数组都是 0-indexed\texttt{0-indexed} 的。

输入格式

Sample Grader 输入格式如下:

nn
p1p_1 p2p_2 \ldots pnp_n

输出格式

Sample Grader 将如下内容输出到标准输出流:

  • 对于每次 query 调用,输出参数 vvquery 的返回值;
  • 对于 answer 调用,输出答案合法性(Correct / Wrong Answer),nn,以及你调用 query 函数的次数 qq

提示

样例交互

样例交互示例如下。

void solve(int N) {
    if (N == 2) {
        std::vector<int> V = {1, 2};
        int qAns = query(V);
        if (qAns == 1) {
            std::vector<int> P = {1, 2};
            answer(P);
        }
    }
}

数据范围

对于 100%100\% 的数据,保证 3n2563\le n\le 256

子任务

编号 nn\le 分值
11 77 1515
22 5050 3535
33 256256 5050

计分方式

令调用 query 函数的次数为 qq

答案错误,超时,内存超限,运行时错误,得 00 分。

否则,得分方式按照如下方式计算:

  • qnq\le n,得 100%100\% 测试点满分。
  • n<q2nn\lt q\le 2n,得 (10.4(qn)n)\left(1-\dfrac{0.4(q-n)}{n}\right) 倍测试点满分(值域为 [0.6,1)[0.6,1),线性递减)。
  • 2n<qn22n\lt q\le n^2,得 (0.60.4(q2n)n22n)\left(0.6-\dfrac{0.4(q-2n)}{n^2-2n}\right) 倍测试点满分(值域为 [0.2,0.6)[0.2,0.6),线性递减)。
  • q>n2q\gt n^2,得 0.20.2 倍测试点满分。

存在得分高于 9898 的官解。