1840. 小强机

单点时限: 2.0 sec

内存限制: 256 MB

特别说明,此题为 sjtu-babyblue 特地为 xiaoqiang 而加。
小强作为华师大学计算机系的学生,免不了要修《计算机科学导论》这门课,以便对本学科产生一种概貌性的认识。在某堂有关机器语言的课上,老师提到了小强机(小强:怎么和我同名 ??)这个概念。他称:众所周知,计算机的功能是极其强大的,也许我们会认为这些功能的实现是由于它内部复杂的电路设计。但是事实上,一台裸机(没有任何软件支持的机器)提供给我们的功能是十分简单的,它的电路设计也只是一些简单模块的组合,但数量极大。像我们的这台小强机只提供了 12 条基本指令,但就是利用如此简单的指令集也同样可以实现非常复杂的功能。

下面介绍一下小强机的结构:

我们的小强机包括一个 CPU (Central Processing Unit)和一个主存储器(Main Memory)。CPU 与主存储器之间用一条总线(Bus)相连。

小强机的主存很小,只有 256 个单元(Cell),每个单元用 00 到 FF 的十六进制整数标识地址(机器内表示为 0000 0000 到 1111 1111)。每个单元能够存储一个字节的信息(即十六进制数 00 到 FF)。

小强机的 CPU 中包含一个运算 / 逻辑单元 ALU (Arithmetic/Logic Unit)和一个控制单元(Control Unit)。其中的 ALU 提供给我们 5 种基本运算(指令集中 5 到 9)。而控制单元中包含一个寄存器组(Register Group),一个程序指针(Program Counter)以及一个指令寄存器(Instruction Register)。其中寄存器组包括 16 个多用途的寄存器从 0 到 F 编号(每个寄存器用一位十六进制数标识,机器内表示为 0000 到 1111)。每个寄存器的可以存储一个字节的信息。程序指针包含一个字节,用于记录主存单元的地址从 00 到 FF。指令寄存器包含 2 个字节,记录一条正在被执行的指令。(小强机的一条完整指令用 2 个字节表示)

再来介绍一下我们小强机的程序执行过程(Program Execution):

控制器完成一项工作要重复进行一个三歩过程即所谓一个指令周期(Machine Cycle)。

  1. 提取 在主存中获取一条指令(地址由程序指针给出)并存储在指令寄存器中,然后使程序指针的值增加 2,指向下一条指令,如果程序指针的值超过 FF 则对 256 取模。

  2. 解码 对存储在指令寄存器中的指令进行解码。如果指令错误(如出现指令不在所给的指令集内等情况),则程序非法结束。

  3. 执行 执行指令寄存器中的指令。如果程序没有结束,则返回第一步。

小强机的输出设备

小强机的输出设备是一台穿孔纸带机(设备编号为 1)。纸带机可在纸带上打孔(有孔处代表 1,无孔处代表 0),代表输出的数值的二进制编码。

最后介绍小强机的指令集:

每条指令由两个主存单元的内容即一个四位 16 进制数构成,分成两个部分,第一部分表示表示要执行的操作(一位 16 进制数),其余 3 位为被操作的对象。

下表列出了小强机的指令集

注意:

  1. 加法溢出情况的处理,如 FF+01=00。

  2. 若指令中 0 的位置(如指令 C000 中有 3 个 0 位置)出现其他的数,不影响指令的执行。末了,老师道:到此为止,相信大家应该对我们的这台小强机已经有所了解。然而到底这台小强机能够发挥多大的作用,还要靠程序员的天才。

你们的任务就是,给出程序员顺序存入小强机主存的 K 段程序(每段程序运行之前所有寄存器清 0,一段程序执行结束后再输入下一段程序),输出当所有程序段都执行完毕后,哪几段程序输出到纸带上的结果是相同的。由于纸带长度很有限,所以程序员规定给每段程序输出的长度为 2 个字节(固定),若输出不足 2 个字节则后面用 0 补足(纸带未被打孔使用),若输出超过 2 个字节或没有输出则视为输出错误。

输入格式

每个测试数据的第一行包含 1 个正整数 K (K≤500),表示有 K 个程序,每个程序包含 257 行,前 256 行每行两位 16 进制数 (中间无空格,用大写字母 A 到 F 表示超过 9 的部分),表示每个主存单元的内容(00 到 FF),第 257 行表示程序指针的内容。

输出格式

第一行输出一个正整数 M,表示把 K 个程序分成 M 个类(ERROR 类也计算在内),每个类中的程序输出到纸带的结果相同。下面 M 行,每行输出一个类的全部元素(空格分隔)。输出完毕后空 6 个空格后输出“OUTPUT:”然后输出纸带上的结果。

注意:

  1. 类的输出顺序按每个类中元素的个数从大到小排列,若元素个数相同的类有多个,则按照每个类的首元素的编号从小到大输出。

  2. 类中元素(程序编号)的输出顺序按编号从小到大输出。

  3. 若程序输出超过 2 个字节或无输出则视为输出错误,归为同一个类 OUTPUT ERROR,先输出一行“OUTPUT ERROR:”再输出一行所有程序名,若没有这样的程序则不输出 OUTPUT ERROR,且位于 PROGRAM ERROR 类之前。

  4. 每个能够正常结束的程序都在 100000 个指令周期内结束。若程序无法正常结束,则要强制退出,且把这类程序与指令错误的程序归为同一个类 PROGRAM ERROR,先输出一行“PROGRAM ERROR”再输出一行所有程序名,若没有这样的程序则不输出 PROGRAM ERROR。

  5. 如果一个程序同时出现 OUTPUT ERROR 和 PROGRAM ERROR 两种错误则只记录在 PROGRAM ERROR 中。

样例

Input
4
11
00
B1
00
C0
00
00
…
00
00 (258行)
00
12
11
B1
02
C2
AB
00
…
00
01 (515行)
32
11
01
00
B1
01
C0
00
00
…
00
00 (772行)
B1
00
B1
00
B1
00
C0
00
00
00
…
00
00 (1029行)
注:由于此题的输入输出过多,过长,请到http://acm.cs.ecnu.edu.cn/downloads/paper/xiaoqiang.in下载
Output
3
1 2 OUTPUT:0001000100000000
OUTPUT ERROR:
4
PROGRAM ERROR:
3
注:
程序1和2 的结果是00010001(后面的0补足空下的字节)
程序3 由于指令错误而退出
程序4 由于输出到纸带机超过2 个字节而出错

1 人解决,8 人已尝试。

1 份提交通过,共有 53 份提交。

9.9 EMB 奖励。

创建: 16 年,10 月前.

修改: 7 年,1 月前.

最后提交: 3 年,11 月前.

来源: N/A

题目标签