NOI2021省选 总结
2020年12月5日的(operatorname{NOIP}2020)之后就是这次省选联考了。
总结一下。
DAY0
说实话,考试之前心态还算比较平和。背了背板子,调了几道小题,很快就到省选。
DAY1
时间分配还是很不好……
总是在想第一题的部分分或正解,导致后面两道题时间很少……
T1
Alice 有 (n) 张卡牌,第 (i)((1 le i le n))张卡牌的正面有数字 (a_i),背面有数字 (b_i),初始时所有卡牌正面朝上。
现在 Alice 可以将不超过 (m) 张卡牌翻面,即由正面朝上改为背面朝上。Alice 的目标是让最终朝上的 (n) 个数字的极差(最大值与最小值的差)尽量小。请你帮 Alice 算一算极差的最小值是多少。
翻译
给定(a[i])和(b[i]),将其中不超过(m)个(a[i],b[i])调换使得(a[1dots n])极差最小。
总结
看完三道题题面觉得这题很简单,看到(nleq10^6)更是“坚定”了写这道题的“信心”。
不久就想到了用优先队列
的“做法”:
- 用两个优先队列维护序列最大值和最小值
- 每次贪心找到最大值和最小值,计算更改两个数值分别对答案的贡献,取其中较优的一种进行更改。
- 期望复杂度$ O( nlog{n})$
于是按照上面的思路写了60行代码
,甚至到编译运行时才发现错误:更改其中一个值后它在另一个优先队列的位置无法确定
,短时间内没有想到更优做法,而且浪费了近一个半小时,为了做后面的题,还是写成了暴力……
最后样例1和样例2正确,样例3TLE。
代码复杂度:(O(n^2log{n}))
期望得分:40
T2
Alice 有一个 (n imes m)的 矩阵 (a_{i, j})((1 le i le n)),其每个元素为大小不超过 ${10}^6 的非负整数。
Bob 根据该矩阵生成了一个 ((n - 1) imes (m - 1)) 的矩阵 (b_{i, j})((1 le i le n - 1),(1 le j le m - 1)),每个元素的生成公式为
[b_{i, j} = a_{i, j} + a_{i, j + 1} + a_{i + 1, j} + a_{i + 1, j + 1} ]现在 Alice 忘记了矩阵 (a_{i, j}),请你根据 Bob 给出的矩阵 (b_{i, j}) 还原出 (a_{i, j})。
翻译
给定一个用公式算出的已知矩阵,用此还原出原矩阵
总结
刚拿到题觉得这道题最可做……
匆匆忙忙写完T1的时候心态有一点问题,居然还在想用这道题拿分。
想用这道题从(n leq 3)的小数据推广到大数据,手推了半个小时之后推不出来,转而写(operatorname{DFS})。
原本以为是和求n个数的集合
类似的题,后来发现在二维矩阵
里写(operatorname{DFS})非常困难……
又用了快一个半小时DeBug这个(operatorname{DFS}),还是很不成功……索性放弃。
代码复杂度:(O(n^3)sim O(n^4))
期望得分:0
T3
对于一张 (n) 个点 (m) 条边的有向图 (G)(顶点从 (1 sim n)编号),定义函数 (f(u, G)):
- 初始化返回值 (cnt = 0) ,图 (G' = G)。
- 从 (1) 至 (n) 按顺序枚举顶点 (v),如果当前的图 (G') 中,从 (u) 到 (v) 与从 (v) 到 (u) 的路径都存在,则将 (cnt + 1),并在图 (G') 中删去顶点 (v) 以及与它相关的边。
- 第 (2) 步结束后,返回值 (cnt) 即为函数值。
现在给定一张有向图 (G),请你求出 (h(G) = f(1, G) + f(2, G) + cdots + f(n, G)) 的值。更进一步地,记删除(按输入顺序给出的)第 (1) 到 (i) 条边后的图为 (G_i)((1 le i le m)),请你求出所有 (h(G_i))的值。
翻译
给定有向图(G),要求求出多次删边前后强连通的个数。
总结
感觉题意是挺难懂的,看了好几遍才明白……
在剩下大概一个小时的时候来写这道题,注意到前(55)分中(nleq 100),想到可以暴力求解。
- 对于每一次输出,暴力求出其(h)值。
- 对于每一次求(h)值,暴力求出其(f)值。
- 对于每一次求(f)值,限定边号在大于(i)的情况下,如果存在(u o v)与(v o u)则直接返回。
结果错误理解了路径都存在
的意思,把最后一个判断改为:
- DFS判断存在(u)到(v)和(v)到(u)的路径;
用了半个小时实现代码,发现输出和答案样例不贴边。
后来发现如下问题:
- 没理解题意的
删掉1~i的边
,导致开始边号从0开始存储 - DFS的返回值有误
- 在
删去一个点及其所有相关的边
时缺少判断条件
用了二十分钟DeBug完,样例1能过了,试了下样例2,答案不对……
此时距离考试结束就剩五分钟了,保存代码准备检查收尾……
代码复杂度:(O(n^3)sim O(n^4))
期望得分:20
DAY1总结
主要还是时间分配的问题……
开场20分钟内只是草草读懂题面,没有去想关于代码实现的问题,导致T1思路错误却在初次写完代码后发现,导致T2认知错误而忽略时间分配。
T1过于注重找正解,T2在错误的思路上走了太长时间……都导致有信心拿部分分的T3没能拿分。
也或许是策略问题吧,又犯了和(operatorname{CSP})一样的错误,在不该耗费长时间的题上又浪费了很多时间。
目标不够明确,以致错误规划。
DAY2
有了DAY1的经验,DAY2开场还是认真读了读题。
T1
欧艾大陆上有 (n) 座城市,城市从 (1 sim n)编号,所有城市经由 (n - 1) 条无向道路互相连通,即 (n) 座城市与 (n - 1) 条道路构成了一棵树。
每座城市的集市上都会出售宝石,总共有 (m) 种不同的宝石,用 (1 sim m) 编号。(i) 号城市的集市出售的是第 (w_i) 种宝石,一种宝石可能会在多座城市的集市出售。
K 神有一个宝石收集器。这个宝石收集器能按照顺序收集至多 (c) 颗宝石,其收集宝石的顺序为:(P_1), (P_2), (ldots) , (P_c)。更具体地,收集器需要先放入第 (P_1) 种宝石,然后才能再放入第 (P_2) 种宝石,之后再能放入第 (P_3) 种宝石,以此类推。其中 (P_1, P_2, ldots , P_c) 互不相等。
K 神到达一个城市后,如果该城市的集市上出售的宝石种类和当前收集器中需要放入的种类相同,则他可以在该城市的集市上购买一颗宝石并放入宝石收集器中;否则他只会路过该城市什么都不做。
现在 K 神给了你 (q) 次询问,每次给出起点 (s_i) 与终点 (t_i),他想知道如果从 (s_i) 号城市出发,沿最短路线走到 (t_i) 号城市后,他的收集器中最多能收集到几个宝石?(在每次询问中,收集器内初始时没有任何宝石。起点与终点城市集市上的宝石可以尝试被收集)
翻译
给定一棵树与树上节点的值,询问从(s)到(t)的最短路上是否可按顺序达到所需的值。
总结
看完三道题后还是觉得只有这道题可做,于是一直在攻这道题,用了大概一个小时五十分钟。
首先想到先找到(s)到(t)的最短路,顺便记录路径,最后顺着路径判断。期望复杂度(O(q n^2))。
在还未写代码的时候想到优化:将找最短路的过程记录改为结构体{当前点编号,走到当前点时收集到的宝石数},可以将复杂度优化到(O(qn))。
用了一个小时把代码敲完,想到T2T3都没什么思路,就继续想着优化。
注意到(u_i=i),(v_i = i + 1),于是做了一个优化,使(s > t)的时候单调向左走,反之单调向右走,或许优化不大……
简单写完了优化,又用了半个小时思考复杂度更优的算法,无果。于是保存,开始看后面题。
代码复杂度:(O(nq))
期望得分:20~36
T2
封榜是 ICPC 系列竞赛中的一个特色机制。ICPC 竞赛是实时反馈提交结果的程序设计竞赛,参赛选手与场外观众可以通过排行榜实时查看每个参赛队伍的过题数与排名。竞赛的最后一小时会进行“封榜”,即排行榜上将隐藏最后一小时内的提交的结果。赛后通过滚榜环节将最后一小时的结果(即每只队伍最后一小时的过题数)公布。
Alice 围观了一场 ICPC 竞赛的滚榜环节。本次竞赛共有 (n) 支队伍参赛,队伍从 (1 sim n) 编号,(i) 号队伍在封榜前通过的题数为 (a_i)。排行榜上队伍按照过题数从大到小进行排名,若两支队伍过题数相同,则编号小的队伍排名靠前。
滚榜时主办方以 (b_i) 不降的顺序依次公布了每支队伍在封榜后的过题数 (b_i)(最终该队伍总过题数为 (a_i + b_i)),并且每公布一支队伍的结果,排行榜上就会实时更新排名。Alice 并不记得队伍被公布的顺序,也不记得最终排行榜上的排名情况,只记得每次公布后,本次被公布结果的队伍都成为了新排行榜上的第一名,以及所有队伍在封榜后一共通过了 (m) 道题(即 (sum_{i = 1}^{n} b_i = m))。
现在 Alice 想请你帮她算算,最终排行榜上队伍的排名情况可能有多少种。
翻译
没太看懂……给出(a[i])和(m),要求问每次给出(b[i])后(a[i]+b[i])都是全序列最大值的可能情况?
总结
还是不太会写……考试时候着重写的T1和T3,最后用的20分钟写这道题也没写出来复杂的判断条件……
代码复杂度:(O(不知道))
期望得分:0
T3
给定一张 (n) 个点 (m) 条边的有向图 (G),其顶点从 (1) 到 (n) 编号。
对于任意两个点 (u,v),若从顶点 (1) 出发到达顶点 (v) 的所有路径都需要经过顶点 (u),则称顶点 (u) 支配顶点 (v)。特别地,每个顶点支配其自身。
对于任意一个点 (v),我们将图中支配顶点 (v) 的顶点集合称为 (v) 的受支配集 (D_v)。
现在有 (q) 次互相独立的询问,每次询问给出一条有向边,请你回答在图 (G) 中加入该条边后,有多少个顶点的受支配集发生了变化。
翻译
大概是有向图中从(1)到(v)必须经过的点为(D_v),在每次独立地给出一条边后判断多少个点的(D)发生变化
总结
写完T1就来看这道题了,在这道题上花了两个小时……
终归想法还是暴力。
-
对于原图:
- 先找一遍从(1)出发到每个点的最短路径并记录下来。
- 列举每个顶点,列举每个中间经过的点,用(operatorname{DFS})判断去除当前顶点后是否可以走到,若不可则当前点仍为
支配集
中的点。 - 如上依次列举后得到原图的(D_i)值。
-
对于每次询问:
- 加上当前给出的边
- 找一遍从(1)出发到每个点的最短路径并记录到另一个数组中
- 列举顶点与到此顶点路径上的点,,用(operatorname{DFS})判断去除当前顶点后是否可以走到
- 得到新图的(D_i)值。
-
与当前询问的(d_i)与原图相减得到答案并输出。
最后是好不容易调通了第一个样例,发现第二个样例还是过不去。用了剩下的时间在调,却没有任何改善……
代码复杂度:(O(n^4))
期望得分:10-20
DAY2总结
这一天的题目比DAY1难写不止一点但题意却更好懂了?
这一场其实挺注重时间分配的,在稍微有把握的(operatorname{T_1})里用了相对较长的时间,其次在(operatorname{T_3})中做了尝试,(operatorname{T_2})题还是放弃了……
总结
估分:70-90
两天的省选也是结束了……说来考试前背的一些板子还是没有用上。
终归来说,感觉自己是比(operatorname{NOIP2020})要有进步的,体现在代码能力和略微提升的时间分配与策略。
应该说是没有犯(NOIP)时的低级错误了吧,尽力写了自己能写的分数。
大概没什么遗憾吧……
下次大考就是(operatorname{CSP2021})了。
接下来计划:
- 稳定住文化课的成绩,提前预习高二上学期课程,为高二停课做准备
- 分配好文化课和竞赛的时间,挤更多时间到机房联系
- 尽量学习考纲内更多的算法,迎接之后的考试。
- 在题库里尽量多刷题
(24OIquad Fighting!)
高二再战!