#P14615. [IATI2022 day1]ones
[IATI2022 day1]ones
时间限制: 1s
空间限制: 256MB
题目类型说明
这是一道提交函数题 / 交互式思维题 / 评分题。
你不需要编写 main 函数,而是需要实现指定函数。系统中存在一个长度为 N 的隐藏 01 串,你可以通过若干次查询来获取信息,并最终返回其中某一段最长连续 1 子段的位置。
题目描述
存在一个隐藏的长度为 N 的比特数组:a_0, a_1, ..., a_{N-1}。
一次查询中,你可以选择若干个位置并翻转这些位置上的比特:
0会变成1;1会变成0。
每次查询之后,评测程序会告诉你:当前数组中最长连续全 1 子数组的长度。
注意,这些翻转是持续生效的。也就是说,前一次查询中被翻转的比特,会一直保持翻转后的状态,直到之后再次被翻转回来。
你的目标是:在完成若干次查询后,找出隐藏数组中某一段最长连续全 1 子数组的位置。如果存在多段同样长的最优答案,返回任意一段即可。
要求使用尽可能少的查询次数。
你需要实现的函数
std::pair<int,int> find_longest_subarray_of_ones(int n);
该函数会在每个子测试中被调用一次,参数 n 表示隐藏数组长度。
你需要返回一对整数 {l, r},表示某个最长连续全 1 子数组的左右端点,其中:
l为左端点下标;r为右端点下标。
你可以调用的查询函数
int flip_bits(const std::vector<bool> &flips);
其中 flips 是一个长度为 N 的比特向量:
flips_i = 1表示需要翻转a_i;flips_i = 0表示不翻转a_i。
在执行这些翻转后,函数会返回当前隐藏序列中最长连续全 1 子数组的长度。
提交要求
你需要提交文件 ones.cpp,其中必须包含:
find_longest_subarray_of_ones函数;- 你自己编写的其他辅助函数或代码。
但不能包含:
main函数;- 任何从标准输入读取数据的代码;
- 任何向标准输出打印内容的代码。
你的程序还必须包含头文件:
#include "ones.h"
本地测试
题目提供了本地评测器 Lgrader.cpp,可与你的程序一起编译测试。
本地评测器输入格式如下:
- 第一行是整数
T,表示本测试中共有多少个子测试; - 对于每个子测试:
- 第一行给出整数
N; - 第二行给出隐藏数组
a_0 ... a_{N-1}。
- 第一行给出整数
如果你的程序运行正确,本地评测器会输出两项信息:
1- 你的程序在所有子测试中使用的最大查询次数。
否则会输出 0。
样例交互说明
假设初始数组为 1,0,1,则一种可能的交互过程如下:
| 选手程序 | 评测程序 |
|---|---|
调用 find_longest_subarray_of_ones(3) |
|
调用 flip_bits({0,0,0}) |
返回 1 |
调用 flip_bits({0,1,0}) |
返回 3 |
返回 {0,2} |
数据范围
T = 51 <= N <= 10^40 <= a_i <= 1
评分方式
如果你的程序在任意一个子测试中出错,则本题得分为 0。
否则,设你的程序在单个子测试中使用的最大查询次数为 Q,则得分为:
当 Q >= 60 时:
当 Q < 60 时:
也就是说,查询次数越少,得分越高。