大模拟的话,大家应该都会,主要就是容易写挂。

操作 1

先理解什么叫做对齐规则。这点我们以样例 2 进行解释:

struct a {
int aa;
short ab;
long ac;
byte ad;
}

那么 aa 占据了 \(0\text{~}3\) 字节的地址,ab 占据了 \(4\text{~}5\) 字节的地址,因为 ac对齐方式为 8,所以要从 \(8\) 字节开始,占据了 \(8\text{~}15\) 字节的地址,ad 占据了第 \(16\) 字节的地址,共占据 \(0\text{~}16\) 共 \(17\) 个字节,最后面因为结构体中最大的对齐方式为 \(8\),所以整个结构体占用了第 \(0\text{~}23\) 字节的地址。

考虑把每个结构体抽象成一个节点,结构体成员指向所对应的其他节点,那么最后整个图就是一个拓扑图,以下面为例:

struct ddd {
short a;
int b;
short c;
};
struct eee {
d a;
int b;
d c;
};
e f;
graph TD
e((eee)) --1--> d((ddd))
e --2--> int((int))
e --3--> d
d --1--> short((short))
d --2--> int((int))
d --3--> short((short))

我们再维护每个节点对于该结构体的内存位置即可。那么操作 1 就顺理成章的完成了。

代码:

void op_1() {
node v;
ll k;
cin >> v.name >> k; for(ll i = 1; i <= k; i++) {
element one;
string type;
cin >> type >> one.name;
one.id = name2id(type); // 通过类型名称找到节点下标 v.align(structs[one.id].kind); // 内存对齐
one.st = v.ti; // 内存起始位置(对于该结构体)
v.ti += structs[one.id].siz;
one.ed = v.ti - 1; // 内存结束位置 v.kind = max(v.kind, structs[one.id].kind);
v.son.push_back(one);
}
v.align(v.kind); // 最后也要对齐
v.siz = v.ti; structs.push_back(v); cout << v.siz << ' ' << v.kind << '\n';
}

操作2

我们再写一个操作纯纯增加码量,其实我们可以把全局变量看做一个大结构体,每次定义全局变量就是在这个结构体内定义成员。

代码:

void op_2() {
element one;
string type;
cin >> type >> one.name;
one.id = name2id(type); rt.align(structs[one.id].kind);
one.st = rt.ti;
rt.ti += structs[one.id].siz;
one.ed = rt.ti - 1; rt.kind = max(rt.kind, structs[one.id].kind);
rt.son.push_back(one); cout << one.st << '\n';
}

操作 3

纯纯搜索即可,我们只需要在每次搜索加上一个偏移量 \(\text{shift}\) 即可:

void op_3() {
string path;
cin >> path; vector<string> path_vec;
string _ = ""; for(auto v : path) {
if(v == '.') {
path_vec.push_back(_);
_ = "";
} else {
_.push_back(v);
}
}
path_vec.push_back(_); path2addr(0, 0, 0, path_vec);
}
void path2addr(ll x, ll pos, ll shift, vector<string> s) {
for(auto v : structs[pos].son) {
if(v.name == s[x]) {
if(x == s.size() - 1) {
cout << shift + v.st << '\n';
return;
}
path2addr(x+1, v.id, shift + v.st, s); // 加上偏移量
return;
}
}
}

操作 4

类比搜索树的写法,我们每次进入一个元素就减去前面的内存即可:

void op_4() {
ll addr;
cin >> addr; addr2path(addr, 0, "");
}
void addr2path(ll addr, ll pos, string path) {
for(auto v : structs[pos].son) {
if(v.st <= addr && addr <= v.ed) { // 注意左右都要满足
if(structs[v.id].flag) { // 注意输出时 path 可能为空,痛失 100pts
if(path == "") cout << v.name << '\n';
else cout << path + '.' + v.name << '\n';
return;
}
if(path == "")
addr2path(addr - v.st, v.id, v.name);// 减去前面的内存位置,得到关于该结构体的内存位置
else
addr2path(addr - v.st, v.id, path + '.' + v.name);
return;
}
}
cout << "ERR\n";
}

完整代码

P9754 [CSP-S 2023] 结构体 题解的更多相关文章

  1. x264_param_t结构体参数分析

    转自:http://blog.chinaunix.net/uid-17053077-id-1987955.html 参考网上的一些资料,结合个人的理解,对x264中x264_param_t结构体作了初 ...

  2. HDU-1495 非常可乐 (嵌套结构体-广搜 对比 一般广搜)

    题意 大家一定觉的运动以后喝可乐是一件很惬意的事情,但是seeyou却不这么认为.因为每次当seeyou买了可乐以后,阿牛就要求和seeyou一起分享这一瓶可乐,而且一定要喝的和seeyou一样多.但 ...

  3. JustOj 2039: 成绩排名 (结构体排序)

    题目描述 每次期末考试成绩出来之前的一段时间大豪哥心里都是痛苦的,总感觉自己会在班上排名特别差.所以当成绩出来以后大豪哥想快点知道班上的总排名,以便知道自己的排名.(PS:大豪哥班上有个学霸名叫日天, ...

  4. (转)x264重要结构体详细说明(1): x264_param_t

    结构体x264_param_t是x264中最重要的结构体之一,主要用于初始化编码器.以下给出了几乎每一个参数的含义,对这些参数的注释有的是参考了网上的资料,有的是自己的理解,还有的是对源代码的翻译,由 ...

  5. x264中重要结构体参数解释,参数设置,函数说明 <转>

    x264中重要结构体参数解释http://www.usr.cc/thread-51995-1-3.htmlx264参数设置http://www.usr.cc/thread-51996-1-3.html ...

  6. C语言 结构体字节对齐问题

    摘选自这位大神的博客 方法一: 结构体在内存中分配一块连续的内存,但结构体内的变量并不一定是连续存放的,这涉及到内存对齐. 原则1  数据成员对齐规则:结构(struct或联合union)的数据成员, ...

  7. PAT 甲级 1080 Graduate Admission (30 分) (简单,结构体排序模拟)

    1080 Graduate Admission (30 分)   It is said that in 2011, there are about 100 graduate schools ready ...

  8. 关于牛客网C语言结构体位域(bit-fields)的一道题

    题目链接地址: https://www.nowcoder.com/questionTerminal/f4e20747a2dd4649bac0c028daa234f4 来源:牛客网 低地址字节 Byte ...

  9. Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final) C. The Delivery Dilemma (贪心,结构体排序)

    题意:你要买\(n\)份午饭,你可以选择自己去买,或者叫外卖,每份午饭\(i\)自己去买需要消耗时间\(b_i\),叫外卖需要\(a_i\),外卖可以同时送,自己只能买完一份后回家再去买下一份,问最少 ...

  10. Codeforces Round #531 (Div. 3) B. Array K-Coloring (结构体排序)

    题意:给你\(n\)个数字,用\(k\)种颜色给他们涂色,要求每个数字都要涂,每种颜色都要用,相同的数字不能涂一样的颜色. 题解:用结构体读入每个数字和它的位置,然后用桶记录每个数字出现的次数,判断是 ...

随机推荐

  1. 多光源渲染方案 - Many Lights Sampling

    目录 Importance Sampling(IS) Light BVH [2018~2019] 预构建 BVH 重建 BVH 基于 BVH node 的 IS Real-time Stochasti ...

  2. BigCode 背后的大规模数据去重

    目标受众 本文面向对大规模文档去重感兴趣,且对散列 (hashing) .图 (graph) 及文本处理有一定了解的读者. 动机 老话说得好: 垃圾进,垃圾出 (garbage in, garbage ...

  3. 信奥赛题1001:Hello,World!

    这个题实在是太简单的了,无法比喻,直接付代码! //c++ #include<bits/stdc++.h> using namespace std; int main() { cout&l ...

  4. Django链接数据库出现的错误以及解决方法

    问题一:django.db.utils.OperationalError: (1045, "Access denied for user 'leo'@'localhost' (using p ...

  5. UI获取元素的几种方式

    通过浏览器驱动获取页面元素的8种方式. 定位方法: 通过webdriver对象的find_element方法 通过 id获取元素 el = driver.find_element(By.ID,'id' ...

  6. Lithosphere是什么,它解决什么问题?

    这问题很好,一针见血,它解决什么问题? 那这得说说,在IoT应用中,我们会碰到什么问题? 和纯软件项目,互联网项目比,IoT应用项目一个比较大不同的地方,应该是它既要做软件,又要做硬件. 我并不是硬件 ...

  7. SpringBoot如何整合spring-retry来实现接口请求重试

    一.重试机制 由于网络不稳定或网络抖动经常会造成接口请求失败的情况,当我们再去尝试就成功了,这就是重试机制. 其主要目的就是要尽可能地提高请求成功的概率,但一般情况下,我们请求第一次失败,代码运行就抛 ...

  8. Avalonia 实现聊天消息渲染、图文混排(支持Windows、Linux、信创国产OS)

       在实现即时通讯软件或聊天软件时,渲染文字表情.图文混排是一项非常繁琐的工作,再加上还要支持GIF动图.引用消息.撤回消息.名片等不同样式的消息渲染时,就更加麻烦了. 好在我们可以使用 ESFra ...

  9. 【故障公告】一而再,再而三,三翻四复:数据库服务器 CPU 100%

    会员救园,故障捣乱,每当困难时,故障们总是喜欢雪上加霜过来考验你. 今天下班前 17:43~17:47 期间,园子的 SQL Server 数据库服务器突然出现 CPU 100% 问题. 发现问题后, ...

  10. 微服务下使用maven做多环境配置

    分享技术,用心生活 前言:很多项目在开发,提测,上线时都会提前手动改一些配置文件来适应对应环境,麻烦不说了,而且也容易出错:生产环境的配置也容易暴露.基于此,我们基于spring cloud alib ...