#P15275. [IOI 2016] Unscrambling a Messy Bug 解读 Bug
[IOI 2016] Unscrambling a Messy Bug 解读 Bug
说明
伊尔沙特是一位软件工程师,他的工作是设计高效的数据结构。有一天,他发明了一个新的数据结构。这个数据结构可以存储一个 位非负整数集合, 是 的整数次幂,即 , 是非负整数。
这个数据结构初始为空。使用该数据结构的程序必须要遵守下列规则:
- 程序可以添加一些元素到这个数据结构中,每次利用函数
add_element(x)添加一个元素,每个元素是一个 位整数。如果程序要添加的元素已经在数据结构中,则什么事情也不会发生。 - 当添加完最后一个元素以后,程序应该调用一次函数
compile_set(),而且只能调用一次。 - 最后,程序可以调用函数
check_element(x)来检查元素 是否在数据结构中。这个函数可以调用多次。
当伊尔沙特第一次实现该数据结构时,他在写函数 compile_set() 时出现一个 bug。这个 bug 将集合中每个元素的二进制位以相同的方式重新排序。伊尔沙特希望你能帮助他找到由于该bug导致的重排列。
考虑一个序列 ,该序列中 到 这n个数字每个数字恰好出现一次。我们称该序列为一个排列。考虑集合中的一个元素,该元素的二进制表达为 ( 是最高位)。当函数 compile_set() 被调用时,这个元素将被元素 替代。
同样的排列 会被用于每个元素的二进制位的重排列。这个排列 可以是任意一个排列,包括 ,。
例如,假设 ,,你已经插入的整数所对应的二进制表示为 0000,1100 和 0111。调用函数 compile_set 会将三个元素分别变成 0000,0101 和 1110。
你的任务是写一个程序,该程序通过和数据结构的交互来找到排列 。该程序应该(按照下列顺序):
- 选择一个 位整数的集合,
- 将这些整数插入到数据结构中,
- 调用函数
compile_set来激活 bug, - 检查某些元素是否在修改以后的集合当中,
- 利用该信息来判断和返回排列 。
注意你的程序只能调用函数 compile_set 一次。
而且,你的程序调用库函数的次数是有限制的。具体的,你的程序可以
- 调用
add_element最多 次( 表示"写") - 调用
check_element最多调用 次( 表示"读")。
实现细节
你应该实现一个函数(方法):
int[] restore_permutation(int n, int w, int r)n:集合中每个元素的二进制表示的位数 (也是排列 的⻓度)。w:你的程序调用函数add_element的最大次数。r:你的程序调用函数check_element的最大次数。- 函数应该返回恢复的排列 。
库函数
为了和数据结构进行交互,你的程序应该使用下列三个函数(方法)
void add_element(string x)
该函数将 所描述的元素添加到集合中。x:一个由0和1构成的字符串,它是要添加到集合中的元素的二进制表示。x的⻓度必须是 。
void compile_set()
该函数必须调用一次且只能调用一次。在调用该函数之后,你的程序不能再调用函数add_element()。在调用该函数之前,你的程序也不能调用函数check_element()。boolean check_element(string x)
该函数检查元素 是否在修改以后的集合当中。x:一个由0和1构成的字符串,它是要检查的元素的二进制表示。x的⻓度必须是 。- 如果元素
x在修改后的集合中,则返回true,否则返回false。
注意:如果你的程序违反上述的任何一条限制,其评分输出将是 "Wrong Answer"。
对于所有的字符串,第一个字符都表示所对应整数的最高位。
评测程序在调用函数 restore_permutation 之前已经确定了排列 。
请使用提供的模板文件,以获得关于你所使用的编程语言的实现细节。
输入格式
样例评测程序
样例评测程序按照以下格式读入输入:
- 第一行: 整数 ,,,
- 第二行: 个整数表示排列 的元素。
实际使用的评测程序与样例评测程序略有不同。
4 16 16
2 1 3 0
2 1 3 0
提示
例子
评测程序执行下列函数调用:
restore_permutation(4, 16, 16)。我们有 而且程序最多执行 次"写"和 次"读"操作。
程序执行下列函数调用:
add_element("0001")add_element("0011")add_element("0100")compile_set()check_element("0001")返回falsecheck_element("0010")返回truecheck_element("0100")返回truecheck_element("1000")返回falsecheck_element("0011")返回falsecheck_element("0101")返回falsecheck_element("1001")返回falsecheck_element("0110")返回falsecheck_element("1010")返回truecheck_element("1100")返回false
只有一个排列和函数 check_element() 返回的值一致:
排列 。因此,restore_permutation 应该返回 [2, 1, 3, 0]。
子任务
- (20 分),,,最多有两个下标 满足 (),
- (18 分),,,
- (11 分),,,
- (21 分),,,
- (30 分),,。
京公网安备 11011102002149号