P9754 题解

发布时间 2024-01-13 16:43:19作者: BlNYU

题意

不难理解,不多赘述。

思路

首先考虑对于性质 A 的情况,我们可以这样做:

定义一个代表变量的结构体,里面存几个参数:首先肯定要存种类(\(type\))和名称(\(name\)),其次为了方便,我们把该变量的大小(\(siz\)),起始位置(\(fir\))和对齐要求(\(mx\))也存了。

操作二

\(type\)\(name\)\(siz\)\(mx\) 可以直接知道,对于 \(fir\),注意到 \(mx\) 最大为 \(8\),所以我们定义一个全局变量 \(siz\) 表示当前占用地址的个数,然后暴力往后面找 \(8\) 个即可。

操作三

我们定义一个 \(map\) \(id\) 来建立变量名与变量编号之间的映射,然后直接查找即可。

操作四

我们把所有变量的 \(fir\) 独立出来建一个数组 \(Fir\),然后直接二分是在哪一个变量范围内,最后通过该变量的 \(siz\) 判断是否为空地址。

接下来我们考虑把 \(1\) 操作加上:

发现对于一个结构体内的过程,其实和全局的过程是相似的,于是我们直接把处理全局的方法搬到结构体里:定义一个代表结构体的结构体,里面放一个代表变量的结构体数组,一个 \(map\) \(id\) 用来建立映射,和一个用来二分起始位置的数组 \(Fir\),最后自然要把结构体包含的变量个数 \(k\) 也存进去(全局也要存)。

操作一

相当于在结构体内做 \(k\) 次操作二,唯一不同的是我们要更新 \(mx\),就是每个变量的 \(mx\)\(\max\)

操作二

跟上面没有区别。

操作三

在上面处理完后进入递归就行。

操作四

同操作三,直接用 string 处理,是否合法可以单独拿一个变量记录一下。

然后就完了。

几个需要注意的点:

  1. 结构体内每个变量需要按变量的对其要求来对齐,而非按结构体的对齐要求来对齐,例如:在一个结构体内先后封装两个 int 和 一个 long 中间是没有“空隙”的。

  2. 注意操作四如果合法最后是没有点的,可以在合法时不输出最后一个字符,也可以在递归时特判,但注意还要在递归外特判

  3. 记得特判 byte,short,int,long。

当然,我们可以把所有的二操作也看成在一个结构体内进行,对于这个结构体的名字,我们可以利用原题中 “所有定义的结构体类型名、成员名称和定义的元素名称均由不超过 \(10\) 个字符的小写字母组成” 这句话,把 \(name\) 设成一个长度为 \(11\) 的字符串,然后把操作全部封装,只需要记录一个结构体名和编号的映射在外面就行,这样码量应该会小一些。