2021-面向对象设计与构造-第三单元总结

第九次作业#

架构与设计策略#

架构上,完全照搬给出的接口,对于每一个接口 (或异常抽象类) A 创建了 MyA 将其实现 (或继承)。

三次作业都是这么做的,因此不在后两次作业中进行赘述了。

绝大部分方法只需复制规格,异常类的实现使用 static 成员变量记录每个 id 的出现次数即可。

三次作业异常类大致相同,因此不在后两次作业中进行赘述了。

无向图中添加点、添加边、查询任意两点间是否连通、查询连通块数量,可以使用路径压缩+启发式合并的并查集,单次操作 O(α(n))O(1) 的复杂度内完成。

因为 idint 范围内且强制在线,需要使用 HashMap 存储,时间上还要乘以一个小常数,不过问题不大。

查询 name 的排名直接复制规格进行暴力,单次复杂度不超过 O(|s|n),其中 |s| 是串长。写平衡树可以优化到 O(|s|logn),但这么小数据范围根本没必要。

测试与 bug 分析#

因为功能过于简单,主要采用随机生成数据和室友对拍的方法。同时构造了一些极端数据防止算法写假。

强测与互测中没有出现 bug,互测中主要采取看代码+构造的方法 hack 了 3 个人,hack 内容见下面的性能分析。

容器选择#

MyNetwork 中使用 HashMap 存储每个 Person,以及并查集中的 fa 数组与 siz 数组,键均为 id

MyPerson 中使用 HashMap 存储边的权值,键为 id

异常类中使用 HashMap 存储每个 id 的出现次数,键为 id

性能分析#

我的实现中,复杂度瓶颈在于查询 name 的排名。

此外,查询连通块数量的 JML 规格是以 O(n2) 次调用 isCircle 方法给出的,如果直接照搬规格, isCircle 的实现又比较慢,就可以被卡成 TLE,互测中也是根据这个问题进行 hack。

第十次作业#

架构与设计策略#

架构上,完全照搬给出的接口,对于每一个接口 (或异常抽象类) A 创建了 MyA 将其实现 (或继承)。

对于 GroupvalueSum,每次新增 Person 或删除 Person 时维护改变量,单次修改复杂度 O(n),单次查询复杂度 O(1)

对于 GroupageMeanageVar,通过维护 age 的和与平方和可以做到单次 O(1) 询问与修改,但是这并不是复杂度瓶颈,索性直接 O(n) 暴力。

剩下的方法就没有什么优化余地了,直接照搬规格即可。

需要注意的是以下两个坑:

  • valueSum 是有序的,每条边的权值要算两次。
  • 一个人可能在好几个组里,addRelation 时要考虑将对应边的权值加到对应的 Group 中。

测试与 bug 分析#

因为功能过于简单,主要采用随机生成数据和室友对拍的方法。同时构造了一些极端数据防止算法写假。

强测与互测中没有出现 bug,互测中主要采取看代码+构造的方法 hack 了 2 个人,hack 内容见下面的性能分析。

组内另有一人使用了 ArrayList 而非 HashMap,看代码时完全忽略,没有针对其进行构造,错失了这个机会。

容器选择#

MyNetwork 中使用 HashMap 存储每个 GroupMessage,键值为对应 id

MyPerson 中使用 ArrayList 存储他收到的信息。

MyGroup 中使用 HashMap 存储其中的 Person,键值为 id

性能分析#

Group 中查询 valueSumJML 规格是以 O(n2) 次调用 isLinked 方法给出的,如果直接照搬规格,可以被卡成 O(n3) 从而造成 TLE,互测中也是根据这个问题进行 hack。

第十一次作业#

架构与设计策略#

架构上,完全照搬给出的接口,对于每一个接口 (或异常抽象类) A 创建了 MyA 将其实现 (或继承)。

除了最短路,其它部分的规格都是单纯模拟,没有优化余地。

对于无负边权的单源最短路,使用优先队列实现的堆优化 Dijkstra 算法可以在 O(mlogm) 的复杂度内完成。

测试与 bug 分析#

因为功能过于简单,主要采用随机生成数据和室友对拍的方法。同时构造了一些极端数据防止算法写假。

强测与互测中没有出现 bug,互测中主要采取看代码+构造的方法进行 hack,但大家写的都很对,因此没有 hack 成功。

容器选择#

MyNetwork 中使用 HashMap 实现规格中的 emojiHeatList

MyNetwork 中利用 PriorityQueue 实现了堆优化 Dijkstra 算法。

性能分析#

在本题的数据范围和 6 秒时限下,单次最短路询问 O(mlogm) 是可以通过的。

不过,需要注意 Dijkstra 的暴力算法并非毫无用途,其复杂度为 O(n2),在稠密图上快于堆优化,例如这个题 CF1528D

总结与收获#

  1. 感谢课程组为我们减负,三次作业简直是从头暴力到尾,老爽了。当然,一个缺点就是写博客不知道写啥,理论课上老师说要我们多写点儿,但是我觉得真的没啥好写的,如果助教审阅时觉得字数太少我可以再水一些(逃

  2. Java8 的 HashMap 非常人性化,当一个哈希值的元素过多时会将链表转化为红黑树,元素过少时又会将红黑树转化为链表,降低了哈希冲突的代价,也让我断绝了我卡哈希的想法

  3. 理论课上老师多次提出:「形式化方法工程应用受限。」

    这三次作业让我深刻体会到了这一点。一些方法寥寥几行就能写完,形式化规格却要写的特别臃肿冗长。如果说这么做的代价是能进行形式化验证,那么意味着可以做到严格意义上的无 bug,简直再好不过了。但是现实是还需要自己造数据进行测试,那「形式化」就会成为效率的阻碍。

    希望以后能看到形式化验证在工程上广泛应用的那一天,这样就再也不用担心没找出来的 bug 了

posted @   JJLeo  阅读(142)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示
主题色彩