ccf#NOI2024B. 百万富翁(richest)

百万富翁(richest)

这是一道交互题。

题目描述

小 Y 的银行有 NN 个客户,编号为 00N1N - 1。客户 iiWiW_i 元存款,且 客户之间的存款金额互不相同

小 P 是小 Y 的深度合作伙伴,他希望知道哪个客户的存款最多。小 P 无法直接获取客户的存款金额,但他可以依次发送若干次 请求,每次 请求 包含若干个 查询,每个 查询 是一个二元组 (i,j)(i, j),表示小 P 想知道客户 ii 和客户 jj 的存款金额哪个更多。如果 Wi>WjW_i > W_j,小 Y 会回答 ii,否则回答 jj

小 P 的 请求tt 和所有请求的 查询 次数总和 ss 有上限,他希望你帮他写一个程序,来找到存款最多的客户。

输入格式

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

选手应确保提交的程序包含头文件 richest.h,可在程序开头加入以下代码实现:

#include "richest.h"

选手需要实现以下函数:

int richest(int N, int T, int S);
  • NN 表示客户的数量;
  • TT 表示对于当前函数调用,请求tt 不应超过此值;
  • SS 表示对于当前函数调用,所有请求的 查询 次数总和 ss 不应超过此值;
  • 该函数需要返回存款最多的客户的编号;
  • 对于每个测试点,该函数 会被交互库调用恰好 1010

选手可以通过调用以下函数向交互库发送一次 请求

std::vector<int> ask(std::vector<int> a, std::vector<int> b);
  • 在调用 ask 函数时需要保证传入参数 aabb 的长度相同,且其中的每个元素都必须是小于 NN 的非负整数,表示该 请求 中的所有 查询
  • 该函数会返回一个类型为 std::vector<int> 且长度与 aabb 相同的变量,设为 cc,其中 c[i]c[i] 表示在客户 a[i]a[i]b[i]b[i] 中存款较多的客户的编号。

题目保证在规定的 请求查询 次数限制下,交互库运行的时间不超过 33 秒,交互库使用的内存大小固定,且不超过 256256 MiB。

测试程序方式

试题目录下的 grader.cpp 是提供的交互库参考实现,最终测试所用的交互库与该参考实现有所不同,因此选手的解法不应该依赖交互库实现。

选手可以在本题目录下使用如下命令编译得到可执行程序:

g++ grader.cpp richest.cpp -o richest -O2 -std=c++14 -static

对于编译得到的可执行程序:

  • 可执行文件将从 标准输入 读入以下格式的数据:
    • 输入的第一行包含四个非负整数 N,T,S,RN, T, S, R,其中 RR 是交互库生成测试数据的随机种子。
  • 输入完成后,交互库将调用 1010 次函数 richest,用输入的参数生成的测试数据进行测试。richest 函数返回后,交互库会输出以下信息:
    • 输出的前 1010 行中,每行首先包含三个整数 r,t,sr, t, s,表示该次执行的结果。其中 rrrichest 函数的返回值,ttss 的含义如题目描述中所示,然后包含该次运行的正确性等消息。
    • 输出的第 1111 行包含 1010 次运行的总信息。

交互示例

假设可执行文件生成的测试数据为 N=4N = 4W=[101,103,102,100]W = [101, 103, 102, 100]T=100T = 100S=100S = 100,下面是一个正确的交互过程:

选手程序 交互库 说明
调用 richest(4, 100, 100) 开始测试
调用 ask([0, 2], [1, 3]) 返回 [1,2][1, 2] W0<W1W_0 < W_1W2>W3W_2 > W_3
调用 ask([0, 2, 3], [1, 1, 1]) 返回 [1,1,1][1, 1, 1] W0<W1W_0 < W_1W2<W1W_2 < W_1W3<W1W_3 < W_1
运行结束并返回 11 向屏幕打印交互结果 交互结束,结果正确

在这个例子中,r=1r=1t=2t=2s=5s=5,满足请求与查询次数的限制。

下发文件说明

在本试题目录下:

  1. grader.cpp 是提供的交互库参考实现。
  2. richest.h 是头文件,选手不用关心具体内容。
  3. template_richest.cpp 是提供的示例代码,选手可在此代码的基础上实现。

选手注意对所有下发文件做好备份。最终评测时只测试本试题目录下的 richest.cpp,对该程序以外文件的修改不会影响评测结果。

数据范围

对于所有测试数据保证:所有 WiW_i 两两不同。

本题共 22 个测试点,每个测试点的分值和数据范围见下表。

测试点编号 分值 N=N = T=T = S=S =
11 1515 10001\,000 11 499500499\,500
22 8585 10000001\,000\,000 2020 20000002\,000\,000

评分方式

注意:

  • 选手不应通过非法方式获取交互库的内部信息,如试图直接读取数组 WW 的值,或直接与标准输入、输出流进行交互。此类行为将被视为作弊;
  • 最终的评测交互库与样例交互库的实现不同,且可能是适应性的:在不与 ask 此前返回的结果相矛盾的前提下,最终的评测交互库可能会动态调整 WW 的值。

本题首先会受到和传统相同的限制,例如编译错误会导致整道题目得 00 分,运行时错误、超过时间限制、超过空间限制都会导致相应测试点得 00 分。选手只能在程序中访问自己定义的和交互库给出的变量或数据,及其相应的内存空间。尝试访问其他位置空间将可能导致编译错误或运行错误。

在每次 richest 函数调用中,程序使用的请求次数 tt 和所有请求的查询次数总和 ss 需在对应限制下,否则将会获得 00 分。

在上述条件基础上:

  • 在测试点 11 中,程序得到满分当且仅当 ask 函数调用合法且 richest 函数返回的答案正确;
  • 在测试点 22 中,程序得到的分数将按照以下方式计算:
    • ask 函数调用不合法,则获得 00 分;
    • ask 函数调用均合法,设 maxt\max t 表示多次调用 richest 函数所得的 tt 的最大值,maxs\max s 表示 ss 的最大值,则程序将获得 85f(maxt)g(maxs)\lfloor 85 \cdot f(\max t) \cdot g(\max s) \rfloor 分,其中 ffgg 的计算方式如下表所示:
maxt\max t f(maxt)f(\max t)
maxt8\max t \leq 8 11
9maxt209 \leq \max t \leq 20 114maxt81 - \frac{1}{4} \sqrt{\max t - 8}
maxs\max s g(maxs)g(\max s)
maxs1099944\max s \leq 1\,099\,944 11
1099945maxs11000431\,099\,945 \leq \max s \leq 1\,100\,043 116log10(maxs1099943)1 - \frac{1}{6} \log_{10} (\max s - 1\,099\,943)
1100044maxs20000001\,100\,044 \leq \max s \leq 2\,000\,000 $\frac{2}{3} - \frac{1}{1\,500}\sqrt{\max s - 1\,100\,043}$

以下是测试点 22 中,不同的 ttss 对得分影响的示例:

maxt\max t maxs\max s 测试点 22 的得分
=20= 20 1099944\leq 1\,099\,944 1111
=19= 19 1414
=18= 18 1717
=17= 17 2121
=16= 16 2424
=15= 15 2828
=14= 14 3232
=13= 13 3737
=12= 12 4242
=11= 11 4848
=10= 10 5454
=9= 9 6363
8\leq 8 [1099974,1099978]\in [1\,099\,974, 1\,099\,978]
[1099969,1099973]\in [1\,099\,969, 1\,099\,973] 6464
[1099965,1099968]\in [1\,099\,965, 1\,099\,968] 6565
[1099962,1099964]\in [1\,099\,962, 1\,099\,964] 6666
[1099959,1099961]\in [1\,099\,959, 1\,099\,961] 6767
[1099957,1099958]\in [1\,099\,957, 1\,099\,958] 6868
[1099955,1099956]\in [1\,099\,955, 1\,099\,956] 6969
[1099953,1099954]\in [1\,099\,953, 1\,099\,954] 7070
=1099952= 1\,099\,952 7171
=1099951= 1\,099\,951 7272
[1099949,1099950]\in [1\,099\,949, 1\,099\,950] 7373
=1099948= 1\,099\,948 7575
=1099947= 1\,099\,947 7676
=1099946= 1\,099\,946 7878
=1099945= 1\,099\,945 8080
1099944\leq 1\,099\,944 8585