#C1040. [CSP-S 2023T3] 结构体

    ID: 4514 传统题 1000ms 256MiB 尝试: 0 已通过: 0 难度: 4 上传者: 标签>CSP-S提高级2023年模拟位运算内存管理数据结构结构体顺序结构

[CSP-S 2023T3] 结构体

题目描述

在本题所描述的语言中,基本类型共有 4 种:byteshortintlong,分别占用 11224488 字节。

定义一个结构体类型时,需要依次给出每个成员的类型和名称。成员类型可以是基本类型,也可以是此前已经定义的结构体类型。定义结构体类型本身不占用内存。

定义一个元素时,元素及其成员按以下规则占用内存:

  • 结构体的成员按定义顺序排列;如果成员本身是结构体,其内部成员也按同样规则排列。
  • 每种类型都有对齐要求。基本类型的对齐要求等于它占用的字节数;结构体类型的对齐要求等于其所有成员对齐要求的最大值。
  • 一种类型的大小以及该类型元素的起始地址,都必须是其对齐要求的整数倍。若当前位置不满足对齐要求,需要空出若干字节后再放置元素。

例如,下面的结构体类型 d 需要按 44 字节对齐,大小为 1212 字节:

struct d {
    short a;
    int b;
    short c;
};

其中成员 a 占用地址 010\sim 1,成员 b 占用地址 474\sim 7,成员 c 占用地址 898\sim 9,最后补齐至 1212 字节。

你需要依次处理 nn 次操作:

  1. 定义一个结构体类型,并输出该类型的大小和对齐要求。
  2. 定义一个元素。所有元素从地址 00 开始按定义顺序放入内存,并满足对齐要求。输出新元素的起始地址。
  3. 通过名称访问元素。结构体成员之间使用 . 连接,例如 a.b.c。输出最内层元素的起始地址。
  4. 访问一个内存地址。如果该地址被某个基本类型元素占用,输出该元素的完整名称;如果该地址位于对齐产生的空隙中,或未被任何元素占用,输出 ERR

输入格式

本题原题采用文件读写,输入文件名为 struct.in,输出文件名为 struct.out。在 Hydro 上提交时,使用标准输入输出即可。

第一行包含一个正整数 nn,表示操作数量。

接下来依次描述 nn 次操作。每次操作首先输入一个正整数 opop

  • op=1op=1,输入一个字符串 ss 和一个正整数 kk,表示新结构体的类型名和成员数量。接下来 kk 行,每行包含两个字符串 ti,nit_i,n_i,表示第 ii 个成员的类型和名称。
  • op=2op=2,输入两个字符串 t,nt,n,表示所定义元素的类型和名称。
  • op=3op=3,输入一个字符串 ss,表示要访问的元素名称。
  • op=4op=4,输入一个非负整数 addraddr,表示要访问的内存地址。

输出格式

对每次操作输出一行,输出内容如下:

  • 操作 1:输出新结构体类型的大小和对齐要求,中间用一个空格分隔。
  • 操作 2:输出新元素的起始地址。
  • 操作 3:输出所访问元素的起始地址。
  • 操作 4:输出占用该地址的基本类型元素的完整名称;若不存在,输出 ERR

样例

5
1 a 2
short aa
int ab
1 b 2
a ba
long bb
2 b x
3 x.ba.ab
4 10
8 4
16 8
0
4
x.bb

来源

CSP-S 2023 第 3 题

数据范围与提示

对于所有测试数据,保证:

  • 1n1001 \le n \le 1001k1001 \le k \le 1000addr10180 \le addr \le 10^{18}
  • 类型名、成员名和元素名均由不超过 1010 个小写英文字母组成,且不与基本类型重名。
  • 所有结构体类型名和元素名互不相同,同一结构体内的成员名互不相同。
  • 所有操作均合法,不会使用未定义的类型,也不会访问不存在的元素或成员。
  • 任意结构体的大小及已定义元素占用的最高内存地址均不超过 101810^{18}
测试点 特殊性质
11 A、D
232\sim 3 A
454\sim 5 B、D
686\sim 8 B
9109\sim 10 C、D
111311\sim 13 C
141614\sim 16 D
172017\sim 20
  • 特殊性质 A:没有操作 1。
  • 特殊性质 B:只有一个操作 1。
  • 特殊性质 C:所有操作 1 中给出的成员类型均为基本类型。
  • 特殊性质 D:使用的基本类型只有 long