#P14386. [JOISC 2017] 故障机器
[JOISC 2017] 故障机器
背景
本题仅允许使用 C++ 提交。因为需要较新版本的编译器,也请不要使用 C++14 (GCC 9)。
洛谷不允许提交两个代码分别运行,所以需要你在提交时把代码合并。与原题不一样的是,你不需要提交两个文件,只需要实现题面中的两个函数。模板代码如下。
extern "C" void Set(int pos, int bit); // 只是一个声明,Set 不是你需要实现的函数
// 这里可以放你需要的头文件
// 这里可以放你需要的全局变量,注意 A 和 B 不共享这些变量,它们在不同的进程中运行
extern "C" void Anna(int N, long long X, int K, int P[]);
extern "C" long long Bruno(int N, int A[]);
保证若无非法操作,交互库占用内存小于 2MB,占用时间小于 450ms。
题目描述
这是一道通信题。
Anna 和 Bruno 是考古学家,他们正在伊朗调查遗迹。
他们的任务如下:Anna 前往遗迹并发现文物,Bruno 在大本营分析结果。
他们的调查计划持续 天。每天,Anna 使用通信设备将结果发送给 Bruno。每天的结果以一个整数 表示。
Anna 每天只能使用一次通信设备。它可发送一个长度为 、由 0 或 1 组成的序列。
然而,该设备已损坏。在长度为 的序列中,存在若干损坏位置。对于损坏位置,无论实际设定值为何,设备总是发送值 0。当 Anna 发送序列时,她可以看到损坏位置的位置,但 Bruno 不知道这些位置。损坏位置的位置和数量每天都会变化。
存在调查可能被延误的危险。由于你是伊朗某国际编程竞赛的参赛者,Anna 和 Bruno 请求你编写一个程序,用于发送他们的调查结果。
任务
编写两个程序,以实现 Anna 和 Bruno 之间的通信:
- 给定序列长度 、待发送的整数 、损坏位置数量 以及损坏位置 ,第一个程序设置 Anna 发送的序列 。
- 给定 Bruno 接收到的序列 ,第二个程序恢复整数 。
在通信设备正常工作的位置,序列 与序列 的值相同。在损坏位置,无论序列 的值为何,序列 总是值 0。
实现细节
你需要提交两个使用相同编程语言编写的文件。
第一个文件为 Anna.c 或 Anna.cpp。该文件用于设置 Anna 发送的序列,并实现以下函数。程序中应包含 Annalib.h。
-
void Anna( int N, long long X, int K, int P[] )对于每个测试用例,该函数将被调用 次。
- 参数 表示待发送序列的长度。
- 参数 是待发送的整数。
- 参数 是损坏位置的数量。
- 参数 是一个长度为 的序列,描述损坏位置的位置。
在函数 Anna 中,必须调用以下函数:
-
void Set( int pos, int bit )该函数用于设置通信设备将要发送的序列 中的某一位。
- 参数
pos是待设置位置的索引,其值必须是介于 0 到 (含)之间的整数。请注意,位置从 0 开始计数。若使用超出此范围的参数调用该函数,你的程序将被视为 Wrong Answer[1]。不允许使用相同的参数pos多次调用该函数;若发生此情况,你的程序将被视为 Wrong Answer[2]。 - 参数
bit是设置到序列第pos位的值,其值必须为 0 或 1。若使用其他参数调用该函数,你的程序将被视为 Wrong Answer[3]。
- 参数
函数 Set 在函数 Anna 中必须被恰好调用 次。当函数 Anna 结束时,若函数 Set 的调用次数与 不一致,你的程序将被视为 Wrong Answer[4]。
若函数 Anna 的调用被视为无效,你的程序将被终止。
第二个文件为 Bruno.c 或 Bruno.cpp。该文件用于恢复表示调查结果的整数,并实现以下函数。程序中应包含 Brunolib.h。
-
long long Bruno( int N, int A[] )对于每个测试用例,该函数将被调用 次。
- 参数 是 Bruno 接收到的序列的长度。
- 参数 是一个长度为 的整数序列,即 Bruno 接收到的序列。
- 函数
Bruno必须恢复出 的值并返回它。
评分流程
评分按以下方式进行。若你的程序被视为 Wrong Answer,则立即被终止。
(1)设置 cnt = 0。
(2)调用函数 Anna 一次。
(3)令 为函数 Anna 设置的序列。在序列 中,将位置 上的值设为 0,得到序列 。以参数 调用函数 Bruno 一次。
(4)设置 。若 ,返回步骤(2);若 ,进入步骤(5)。
(5)你的程序将被评分。
重要提示
- 运行时间和内存使用量将根据评分流程中的步骤(1)、(2)、(3)、(4)进行计算。
- 你的程序在步骤(2)中调用函数
Anna或在步骤(3)中调用函数Bruno时,不得被视为 Wrong Answer。你的程序必须在无运行时错误的情况下执行。 - 你的程序可以为内部用途实现其他函数,或使用全局变量。提交的程序将与评分器一起编译,并生成一个单一的可执行文件。所有全局变量和内部函数应声明为
static,以避免与其他文件发生冲突。由于在评分时,Anna 和 Bruno 的程序将作为两个独立的进程执行,它们无法共享全局变量。 - 在整个过程中,函数
Anna和Bruno各自将被调用 次。你的程序中使用的变量应被适当初始化。 - 你的程序不应使用标准输入和标准输出。你的程序不得通过任何方式与其他文件通信。
编译与测试运行
你可以从竞赛网页下载一个归档文件,其中包含一个用于测试你程序的示例评分器。该归档文件还包含你程序的一个示例源代码文件。
示例评分器由一个源文件组成,该文件为 grader.c 或 grader.cpp。例如,若你的程序为 Anna.c 和 Bruno.c,或 Anna.cpp 和 Bruno.cpp,则你可运行以下命令编译你的程序:
- C
gcc -std=c11 -O2 -o grader grader.c Anna.c Bruno.c -lm
- C++
g++ -std=c++14 -O2 -o grader grader.cpp Anna.cpp Bruno.cpp
当编译成功后,将生成可执行文件 grader。
请注意,实际的评分器与示例评分器不同。示例评分器将以单个进程形式运行,它将从标准输入读取输入数据,并将结果写入标准输出。
输入格式
示例评分器从标准输入读取以下数据:
- 第一行包含一个整数 。
- 接着,给出 个查询的信息。
- 每个查询的信息由两行组成,具体如下:
- 第一行包含三个以空格分隔的整数 、、。这表示待发送序列的长度为 ,Anna 要发送的整数为 ,且有 个损坏位置。
- 第二行包含 个以空格分隔的整数 。这意味着,对于每个 (),序列中第 个位置是损坏的。
输出格式
当程序成功终止时,示例评分器将以下信息写入标准输出。(引号本身不会被实际输出。)
- 若你的程序被视为 Wrong Answer,示例评分器将以如下格式输出其类型:“Wrong Answer [1]”,随后你的程序将被终止。
- 若每次对函数
Anna的调用均未被视为 Wrong Answer,示例评分器将输出 “Accepted” 及值 。关于 的取值,请参见“评分”部分。
若你的程序被视为多种类型的 Wrong Answer,示例评分器仅报告其中一种。
提示
数据范围
所有输入数据均满足以下条件:
- 。
- 。
- 。
- 。
- ()。
- ()。
评分
-
令 为本题所有测试用例中以下值的最小值:
- 满足条件的最大整数 ,使得对于每个满足 的查询,Bruno 均能正确回答出 的值。
-
本题的得分按以下方式计算:
- 若 ,得分为 分。
- 若 ,得分为 分。
- 若 ,得分为 分。
- 若 ,得分为 分。