这是一道交互题。
题目描述
小 Y 的银行有 N N N 个客户,编号为 0 0 0 到 N − 1 N - 1 N − 1 。客户 i i i 有 W i W_i W i 元存款,且 客户之间的存款金额互不相同 。
小 P 是小 Y 的深度合作伙伴,他希望知道哪个客户的存款最多。小 P 无法直接获取客户的存款金额,但他可以依次发送若干次 请求 ,每次 请求 包含若干个 查询 ,每个 查询 是一个二元组 ( i , j ) (i, j) ( i , j ) ,表示小 P 想知道客户 i i i 和客户 j j j 的存款金额哪个更多。如果 W i > W j W_i > W_j W i > W j ,小 Y 会回答 i i i ,否则回答 j j j 。
小 P 的 请求 数 t t t 和所有请求的 查询 次数总和 s s s 有上限,他希望你帮他写一个程序,来找到存款最多的客户。
输入格式
选手不需要,也不应该实现 main
函数。
选手应确保提交的程序包含头文件 richest.h
,可在程序开头加入以下代码实现:
#include "richest.h"
选手需要实现以下函数:
int richest(int N, int T, int S);
N N N 表示客户的数量;
T T T 表示对于当前函数调用,请求 数 t t t 不应超过此值;
S S S 表示对于当前函数调用,所有请求的 查询 次数总和 s s s 不应超过此值;
该函数需要返回存款最多的客户的编号;
对于每个测试点,该函数 会被交互库调用恰好 10 10 10 次 。
选手可以通过调用以下函数向交互库发送一次 请求 :
std::vector<int> ask(std::vector<int> a, std::vector<int> b);
在调用 ask
函数时需要保证传入参数 a a a 和 b b b 的长度相同,且其中的每个元素都必须是小于 N N N 的非负整数,表示该 请求 中的所有 查询 ;
该函数会返回一个类型为 std::vector<int>
且长度与 a a a 和 b b b 相同的变量,设为 c c c ,其中 c [ i ] c[i] c [ i ] 表示在客户 a [ i ] a[i] a [ i ] 和 b [ i ] b[i] b [ i ] 中存款较多的客户的编号。
题目保证在规定的 请求 与 查询 次数限制下,交互库运行的时间不超过 3 3 3 秒,交互库使用的内存大小固定,且不超过 256 256 256 MiB。
测试程序方式
试题目录下的 grader.cpp
是提供的交互库参考实现,最终测试所用的交互库与该参考实现有所不同,因此选手的解法不应该依赖交互库实现。
选手可以在本题目录下使用如下命令编译得到可执行程序:
g++ grader.cpp richest.cpp -o richest -O2 -std=c++14 -static
对于编译得到的可执行程序:
可执行文件将从 标准输入 读入以下格式的数据:
输入的第一行包含四个非负整数 N , T , S , R N, T, S, R N , T , S , R ,其中 R R R 是交互库生成测试数据的随机种子。
输入完成后,交互库将调用 10 10 10 次函数 richest
,用输入的参数生成的测试数据进行测试。richest
函数返回后,交互库会输出以下信息:
输出的前 10 10 10 行中,每行首先包含三个整数 r , t , s r, t, s r , t , s ,表示该次执行的结果。其中 r r r 是 richest
函数的返回值,t t t 和 s s s 的含义如题目描述中所示,然后包含该次运行的正确性等消息。
输出的第 11 11 11 行包含 10 10 10 次运行的总信息。
交互示例
假设可执行文件生成的测试数据为 N = 4 N = 4 N = 4 ,W = [ 101 , 103 , 102 , 100 ] W = [101, 103, 102, 100] W = [ 101 , 103 , 102 , 100 ] ,T = 100 T = 100 T = 100 ,S = 100 S = 100 S = 100 ,下面是一个正确的交互过程:
选手程序
交互库
说明
调用 richest(4, 100, 100)
开始测试
调用 ask([0, 2], [1, 3])
返回 [ 1 , 2 ] [1, 2] [ 1 , 2 ]
W 0 < W 1 W_0 < W_1 W 0 < W 1 ,W 2 > W 3 W_2 > W_3 W 2 > W 3
调用 ask([0, 2, 3], [1, 1, 1])
返回 [ 1 , 1 , 1 ] [1, 1, 1] [ 1 , 1 , 1 ]
W 0 < W 1 W_0 < W_1 W 0 < W 1 ,W 2 < W 1 W_2 < W_1 W 2 < W 1 ,W 3 < W 1 W_3 < W_1 W 3 < W 1
运行结束并返回 1 1 1
向屏幕打印交互结果
交互结束,结果正确
在这个例子中,r = 1 r=1 r = 1 ,t = 2 t=2 t = 2 ,s = 5 s=5 s = 5 ,满足请求与查询次数的限制。
下发文件说明
在本试题目录下:
grader.cpp
是提供的交互库参考实现。
richest.h
是头文件,选手不用关心具体内容。
template_richest.cpp
是提供的示例代码,选手可在此代码的基础上实现。
选手注意对所有下发文件做好备份。最终评测时只测试本试题目录下的 richest.cpp
,对该程序以外文件的修改不会影响评测结果。
数据范围
对于所有测试数据保证:所有 W i W_i W i 两两不同。
本题共 2 2 2 个测试点,每个测试点的分值和数据范围见下表。
测试点编号
分值
N = N = N =
T = T = T =
S = S = S =
1 1 1
15 15 15
1 000 1\,000 1 000
1 1 1
499 500 499\,500 499 500
2 2 2
85 85 85
1 000 000 1\,000\,000 1 000 000
20 20 20
2 000 000 2\,000\,000 2 000 000
评分方式
注意:
选手不应通过非法方式获取交互库的内部信息,如试图直接读取数组 W W W 的值,或直接与标准输入、输出流进行交互。此类行为将被视为作弊;
最终的评测交互库与样例交互库的实现不同,且可能是适应性的:在不与 ask
此前返回的结果相矛盾的前提下,最终的评测交互库可能会动态调整 W W W 的值。
本题首先会受到和传统相同的限制 ,例如编译错误会导致整道题目得 0 0 0 分,运行时错误、超过时间限制、超过空间限制都会导致相应测试点得 0 0 0 分。选手只能在程序中访问自己定义的和交互库给出的变量或数据,及其相应的内存空间。尝试访问其他位置空间将可能导致编译错误或运行错误。
在每次 richest
函数调用中,程序使用的请求次数 t t t 和所有请求的查询次数总和 s s s 需在对应限制下,否则将会获得 0 0 0 分。
在上述条件基础上:
在测试点 1 1 1 中,程序得到满分当且仅当 ask
函数调用合法且 richest
函数返回的答案正确;
在测试点 2 2 2 中,程序得到的分数将按照以下方式计算:
若 ask
函数调用不合法,则获得 0 0 0 分;
若 ask
函数调用均合法,设 max t \max t max t 表示多次调用 richest
函数所得的 t t t 的最大值,max s \max s max s 表示 s s s 的最大值,则程序将获得 ⌊ 85 ⋅ f ( max t ) ⋅ g ( max s ) ⌋ \lfloor 85 \cdot f(\max t) \cdot g(\max s) \rfloor ⌊ 85 ⋅ f ( max t ) ⋅ g ( max s )⌋ 分,其中 f f f 与 g g g 的计算方式如下表所示:
max t \max t max t
f ( max t ) f(\max t) f ( max t )
max t ≤ 8 \max t \leq 8 max t ≤ 8
1 1 1
9 ≤ max t ≤ 20 9 \leq \max t \leq 20 9 ≤ max t ≤ 20
1 − 1 4 max t − 8 1 - \frac{1}{4} \sqrt{\max t - 8} 1 − 4 1 max t − 8
max s \max s max s
g ( max s ) g(\max s) g ( max s )
max s ≤ 1 099 944 \max s \leq 1\,099\,944 max s ≤ 1 099 944
1 1 1
1 099 945 ≤ max s ≤ 1 100 043 1\,099\,945 \leq \max s \leq 1\,100\,043 1 099 945 ≤ max s ≤ 1 100 043
1 − 1 6 log 10 ( max s − 1 099 943 ) 1 - \frac{1}{6} \log_{10} (\max s - 1\,099\,943) 1 − 6 1 log 10 ( max s − 1 099 943 )
1 100 044 ≤ max s ≤ 2 000 000 1\,100\,044 \leq \max s \leq 2\,000\,000 1 100 044 ≤ max s ≤ 2 000 000
$\frac{2}{3} - \frac{1}{1\,500}\sqrt{\max s - 1\,100\,043}$
以下是测试点 2 2 2 中,不同的 t t t 和 s s s 对得分影响的示例:
max t \max t max t
max s \max s max s
测试点 2 2 2 的得分
= 20 = 20 = 20
≤ 1 099 944 \leq 1\,099\,944 ≤ 1 099 944
11 11 11
= 19 = 19 = 19
14 14 14
= 18 = 18 = 18
17 17 17
= 17 = 17 = 17
21 21 21
= 16 = 16 = 16
24 24 24
= 15 = 15 = 15
28 28 28
= 14 = 14 = 14
32 32 32
= 13 = 13 = 13
37 37 37
= 12 = 12 = 12
42 42 42
= 11 = 11 = 11
48 48 48
= 10 = 10 = 10
54 54 54
= 9 = 9 = 9
63 63 63
≤ 8 \leq 8 ≤ 8
∈ [ 1 099 974 , 1 099 978 ] \in [1\,099\,974, 1\,099\,978] ∈ [ 1 099 974 , 1 099 978 ]
∈ [ 1 099 969 , 1 099 973 ] \in [1\,099\,969, 1\,099\,973] ∈ [ 1 099 969 , 1 099 973 ]
64 64 64
∈ [ 1 099 965 , 1 099 968 ] \in [1\,099\,965, 1\,099\,968] ∈ [ 1 099 965 , 1 099 968 ]
65 65 65
∈ [ 1 099 962 , 1 099 964 ] \in [1\,099\,962, 1\,099\,964] ∈ [ 1 099 962 , 1 099 964 ]
66 66 66
∈ [ 1 099 959 , 1 099 961 ] \in [1\,099\,959, 1\,099\,961] ∈ [ 1 099 959 , 1 099 961 ]
67 67 67
∈ [ 1 099 957 , 1 099 958 ] \in [1\,099\,957, 1\,099\,958] ∈ [ 1 099 957 , 1 099 958 ]
68 68 68
∈ [ 1 099 955 , 1 099 956 ] \in [1\,099\,955, 1\,099\,956] ∈ [ 1 099 955 , 1 099 956 ]
69 69 69
∈ [ 1 099 953 , 1 099 954 ] \in [1\,099\,953, 1\,099\,954] ∈ [ 1 099 953 , 1 099 954 ]
70 70 70
= 1 099 952 = 1\,099\,952 = 1 099 952
71 71 71
= 1 099 951 = 1\,099\,951 = 1 099 951
72 72 72
∈ [ 1 099 949 , 1 099 950 ] \in [1\,099\,949, 1\,099\,950] ∈ [ 1 099 949 , 1 099 950 ]
73 73 73
= 1 099 948 = 1\,099\,948 = 1 099 948
75 75 75
= 1 099 947 = 1\,099\,947 = 1 099 947
76 76 76
= 1 099 946 = 1\,099\,946 = 1 099 946
78 78 78
= 1 099 945 = 1\,099\,945 = 1 099 945
80 80 80
≤ 1 099 944 \leq 1\,099\,944 ≤ 1 099 944
85 85 85