QOJ.ac

QOJ

時間限制: 10 s 記憶體限制: 512 MB 總分: 100 难度: [顯示] 互動 可 Hack ✓

#24229. 慕斯

统计

本题为交互题。

在甜品节即将开幕的前夕,主厨正在精心雕琢店里的招牌名作——“千层幻彩慕斯”。这道甜品由 $n$ 块风味各异的慕斯组合而成,编号依次为 $0,1,\dots,n-1$。

然而在慌乱之中,助手不小心混淆了慕斯的摆放次序。如今它们从左到右一字排开,形成了一个未知的位置排列 $p=(p_0,p_1,\dots,p_{n-1})$,其中 $p_i$ 代表第 $i$ 个位置上放置的慕斯编号。

为了厘清每块慕斯的准确位置,你可以借助甜品测试仪进行检测。每次选定三个互不相同的位置 $x,y,z$,测试仪便能反馈这三块慕斯中最小与最大编号之和:

$$ \min(p_x,p_y,p_z)+\max(p_x,p_y,p_z). $$

开幕钟声即将敲响,你能否通过有限次的检测,准确还原出每一块慕斯的真实位置?


有一个长度为 $n$ 的排列 $p$,其元素恰好为 $0,1,\ldots,n-1$。你不知道 $p$ 的具体内容。

你可以选取三个互不相同的下标 $x,y,z$,交互库会返回

$$ \min(p_x,p_y,p_z)+\max(p_x,p_y,p_z). $$

你的任务是还原整个排列。询问次数上限和根据询问次数计算分数的方式见下文。

实现细节

选手不需要,也不应该实现 main 函数。提交的源文件应包含:

#include "mousse.h"

你需要实现以下两个函数:

void init(int c);
std::vector<int> mousse(int c, int n);
  • $c$ 为子任务编号;$c=0$ 表示样例。每个测试点恰好包含一组数据。交互库对该测试点调用一次 init(c),随后调用一次 mousse(c,n)。
  • mousse 应返回长度为 $n$ 的数组,其中第 $i$ 个元素为 $p_i$,下标从 $0$ 开始。

选手可以调用以下函数进行一次询问:

int query(int x, int y, int z);

必须满足 $0\le x,y,z < n$,且 $x,y,z$ 两两不同。函数返回 $\min(p_x,p_y,p_z)+\max(p_x,p_y,p_z)$。

测试程序方式

附件包含 mousse.h、本地交互库 grader.cpp 和示例程序 template_mousse.cpp。将自己的程序保存为 mousse.cpp,可以在本题目录下运行:

g++ grader.cpp mousse.cpp -o mousse -O2 -std=c++14
./mousse < mousse1.in

本地交互库从标准输入读入隐藏排列,选手程序不得自行读取这些数据。输入格式如下:

  • 第一行两个整数 $c,n$。
  • 第二行输入 $p_0,p_1,\ldots,p_{n-1}$。

如果答案正确,交互库输出 Correct! 和 Max queries used: Q,其中 $Q$ 是该测试点的询问次数;如果答案错误,输出 Wrong answer.。传入非法询问或超出询问次数上限时,程序向标准错误流输出错误信息并退出。可以添加 -v 参数查看该测试点的询问次数。

样例

input

0 10
0 2 9 1 5 8 3 7 6 4

output

Correct!
Max queries used: 15

explanation

例如调用 query(0,1,2) 时,三个对应数值为 $0,2,9$,返回 $0+9=9$。参考程序在这组数据中使用 $15$ 次询问。你使用其他策略时,这个次数可以不同。

数据范围

对于所有测试数据,$n\in\{10,100,10^5\}$,$p$ 为 $0\sim n-1$ 的排列。每个测试点恰好包含一组数据。

子任务编号 分值 $n =$ $Q_{\max} = $ 特殊性质
$1$ $5$ $10$ $1000$ 无
$2$ $5$ $100$ $10000$ 无
$3$ $30$ $10^5$ $2\times10^6$ $p_0=0$
$4$ $60$ $10^5$ $2\times10^6$ 无

样例的 $c=0$、$n=10$,询问上限为 $1000$。

评分方式

注意:

  • 交互库不是适应性的。每个测试点的排列在调用选手程序前已经确定,不会随询问改变。
  • 选手不得通过读取标准输入或其他非法方式获取隐藏排列。最终评测使用的交互库与本地交互库的实现可能不同。

若某测试点中 mousse 返回错误答案、query 的参数不合法,或询问次数超过该子任务的 $Q_{\max}$,该测试点的得分倍率为 $0$。

子任务 $1,2$ 中,只有全部测试点正确才能获得该子任务的全部分数。

对于子任务 $3,4$,若任一测试点的得分倍率为 $0$,该子任务得 $0$ 分。否则,令 $Q$ 为该子任务所有测试点中的最大询问次数,得分倍率 $f(Q)$ 由下表确定:

询问次数 $Q_i$ 得分倍率 $f_i$
$99970$ $100\%$
$99975$ $98\%$
$99981$ $95\%$
$99988$ $90\%$
$99996$ $84\%$
$100000$ $80\%$
$100010$ $74\%$
$100026$ $66\%$
$100051$ $58\%$
$100093$ $52\%$
$150000$ $32\%$
$200000$ $20\%$
$1660964$ $8\%$
$2000000$ $5\%$

若 $Q\le 99970$,则 $f(Q)=100\%$。若 $Q$ 位于表中相邻两行 $(Q_i,f_i)$ 与 $(Q_{i+1},f_{i+1})$ 之间,则有:

$$ f(Q)=f_i+\frac{Q-Q_i}{Q_{i+1}-Q_i}(f_{i+1}-f_i). $$

子任务 $3$ 的得分为 $30f(Q)$,子任务 $4$ 的得分为 $60f(Q)$。最终得分按小数点后 $3$ 位四舍五入。

时间限制:$10\ \mathrm{s}$。

空间限制:$512\ \mathrm{MiB}$。

Editorials

IDTypeStatusTitlePosted ByLast UpdatedActions
#2924EditorialOpenNew Editorial for Problem #24229wangmaruiView

Discussions

About Discussions

The discussion section is only for posting: General Discussions (problem-solving strategies, alternative approaches), and Off-topic conversations.

This is NOT for reporting issues! If you want to report bugs or errors, please use the Issues section below.

Open Discussions 0
No discussions in this category.

Issues

About Issues

If you find any issues with the problem (statement, scoring, time/memory limits, test cases, etc.), you may submit an issue here. A problem moderator will review your issue.

Guidelines:

  1. This is not a place to publish discussions, editorials, or requests to debug your code. Issues are only visible to you and problem moderators.
  2. Do not submit duplicated issues.
  3. Issues must be filed in English or Chinese only.
Active Issues 0
No issues in this category.
Closed/Resolved Issues 0
No issues in this category.