#P14416. [JOISC 2015] 有限记忆 / Limited Memory
[JOISC 2015] 有限记忆 / Limited Memory
题目背景
翻译来自于 LibreOJ
题目描述
JOI 酱被选为了日本代表去参加国际信息学奥林匹克竞赛。为了提高信息处理速度,日本国际信息学奥林匹克竞赛委员会的 K 理事长提出了一个课题。
K 理事长在纸上写下了一个字符串 ,仅由 <,>,[ 和 ] 组成,但是 JOI 酱不知道字符串具体是什么。JOI 酱会被告知字符串的长度,他的课题是判断字符串 是不是一个合法字符串。合法字符串的定义如下:
- 空字符串(长度为 的字符串)是合法字符串。
- 假设 是一个合法字符串,那么
<>也是合法字符串。 - 假设 是一个合法字符串,那么
[]也是合法字符串。 - 假设 和 都是合法字符串,那么 也是合法字符串。
例如 <>[] 和 [<>]<> 都是合法字符串,而 >< 和 [<]> 都不是合法字符串。
每天的中午,JOI 酱可以给 K 理事长打一个电话。电话里,JOI 酱可以指定一个整数 ,K 理事长会告诉他字符串 的第 个字符。
现在 JOI 酱有一个限制:不能用其它东西记录这个课题相关的笔记。JOI 酱每天晚上 点睡觉,早上 点起床。在睡眠中,她只能在脑中记下 比特的信息。更准确的说,她会在睡前把一个 到 的整数记在脑内,然后第二天醒来根据这个整数来做决策。由于字符串长度是一开始就被告知的,JOI 酱是一直知道这个信息的。
JOI 酱每天睡前可以记住一个整数,或者发邮件告诉 K 理事长字符串 是不是一个合法字符串。在后者的情况下,这个课题就结束了,K 理事长会判定你是否完成了这个课题。注意,邮件必须在课题开始后 天内发给 K 理事长,不然你就算没有完成这个课题。
题目
实现 JOI 酱的策略,编写一个程序,能够正确解决上述课题。
实现细节
你需要实现一个过程来确定字符串是否正确。你不需要引入外部头文件,但是你应当声明函数 char Get(int I);。
程序需要实现以下过程。
int Memory(int N, int M)- 参数 表示字符串 的长度。
- 参数 表示上一天睡前记下的整数,在课题一开始的时候 。
- 在这个函数里必须恰好调用一次
Get函数。 - 函数的返回值必须是一个 到 的整数,或者 ,或者 。如果返回值不在这些数里面,那么你的程序会被判为
Wrong Answer [1]。- 返回值是 到 的整数的话,表示这是睡前记下的数字。
- 返回值是 的话,表示用邮件回答 是一个合法字符串。
- 返回值是 的话,表示用邮件回答 不是一个合法字符串。
- 这个函数应该理论上只依赖 , 和
Get的返回值进行决策。在实际评测过程中这个函数会被调用 次,更详细的信息请参考「评分的顺序」。
此外,程序中可以调用如下函数。
char Get(int I)- 这个函数只能在调用
Memory函数的时候被调用一次,如果调用了不止一次,你的程序会被判为Wrong Answer [2]。 - 参数 是一个 到 的整数,不满足此条件时,会被判为
Wrong Answer [3]。 - 返回值是 的第 个字符。
- 这个函数只能在调用
评分的顺序
每个测试文件会包含多组测试数据,每组测试数据对应的字符串 的长度 是一样的。评测过程如下,如果一旦被判定为了 Wrong Answer,你的程序会立刻被终止。
-
在给出参数 , 和
Get的返回值的情况下,检查函数Memory的行为。也就是说对于满足 的整数 ,做如下操作:- 对于每个在
<,>,[和]的字符 ,会执行如下操作:把 和 作为参数传给Memory函数,当Get被调用的时候,把 返回出去。用 表示函数Memory的返回值。 - 上述操作会调用 次
Memory函数,需要检测Get的调用是否一致。如果Get被调用了,那么这 次传给Get的参数I必须一样。如果Get没有被调用,那么这 次Memory的返回值必须要一样。不满足此条件时,会被判为Wrong Answer [4]。当Get被调用的时候,我们令 表示 的值(如果没有被调用 )。
- 对于每个在
-
对于每组数组里的字符串 ,如下操作会被用来模拟课题描述
- 一开始 。
- 重复执行如下操作:
- 令 是 的第 个字符。
- 把 换为 。
- 或者 的情况下,跳出这个循环,进入下个流程。
- 如果循环了超过 次,你的程序会被判为
Wrong Answer [5]。
- 如果是以下某个情况,你的程序会被判为
Wrong Answer [6]。- 是一个合法字符串,但是 。
- 不是一个合法字符串,但是 。
-
你的程序被认为是正确的。
编译与运行方法
「附加文件」中提供了 memory.h、grader-simple.c、grader-simple.cpp、grader-strict.c 和 grader-strict.cpp 五个文件。若你编写的程序名称为 memory.c 或 memory.cpp,请运行以下命令来编译:
- C 语言:
gcc -std=c11 -O2 -o grader-simple grader-simple.c memory.c -lmgcc -std=c11 -O2 -o grader-strict grader-strict.c memory.c -lm
- C++ 语言:
g++ -std=c++14 -O2 -o grader-simple grader-simple.cpp memory.cppg++ -std=c++14 -O2 -o grader-strict grader-strict.cpp memory.cpp
当命令成功时,会产生一个可执行文件 grader-simple 或者 grader-strict。
注意实际评测时的程序与下发的样例评测程序并不相同。实际的 memory.h 函数实现将通过标准输入/输出与单独运行的交互器进行交互。
样例程序评测概要
grader-simple 不会模拟「评分的顺序」的第一步,但是会模拟课题的操作,具体可以参考「样例交互」。grader-strict 会严格按照「评分的顺序」执行。两者在输出上会有如下的不同:
grader-simple不会输出Wrong Answer [4],因为它并没有模拟这个操作grader-simple和grader-strict不会输出Wrong Answer [6],但是会输出 的值。
输入格式
grader-simple 和 grader-strict 将从标准输入读入以下数据。
- 第一行包含两个整数 和 (),表示字符串 的长度和测试数据组数。
- 接下来 行,每行包含一个长度为 的字符串 。
输出格式
如果评测程序正常结束,grader-simple 和 grader-strict 将向标准输出输出以下信息。
- 程序正常结束的话,会输出 的值。
- 运行过程中被判为错误时,以
Wrong Answer [x]的格式报告并退出。
4 1
<>[]
提示
数据范围
所有输入数据满足以下条件:
- 的长度
- 的每个字符是 '<', '>', '[', ']' 中的一个。
子任务
子任务 1 [10 分]
- 的长度
子任务 2 [10 分]
- 的长度
子任务 3 [5 分]
- 的长度
子任务 4 [5 分]
- 的长度
子任务 5 [10 分]
- 的每个字符是 '<' 或 '>' 中的一个。
子任务 6 [60 分]
无额外限制。