NOIP2018普及组复赛解题

2019年NOIP全套教程
NOIP2018普及组复赛解题报告,旨在对于NOIP2018普及组复赛题目进行解答和分析,并基于试卷分析对NOIP普及组选手的训练提出建议。本报告内容代表作者个人思想,由于测试数据尚未公布,暂时无法对其中代码进行测评。为了不影响阅读的连贯性,本报告中所有题目的原题和代码均另行发布。

T1 标题统计(titel)

思路:本题是一道标准的送分题,按照题目要求将字符串读入即可。需要注意的是,本题的输入中可能存在空格,用常规的scanf或cin无法完成读入,须借助EOF或getline函数,这也是近15年来NOIP普及组复赛中首次涉及EOF和getline。

评价:本题在历届NOIP普及组第一题中属于较为简单的题目,但其首次考察了EOF或getline的应用,使得不少优秀考生折戟。好在数据设置尚为仁慈,80%的数据可用常规的scanf或cin通过。
虽然在复赛中从未考察过getline函数,但在NOIP2015的普及组复赛中,阅读程序写结果第二题即对geiline函数有所涉及。这提示我们应当对初赛中涉及到较为冷门的函数和用法提高重视程度,出题人写在试卷上的就是他认为选手应当掌握的。

T2 龙虎斗(fight)

思路:本题思路清晰,可按照题目要求计算出两队的势力值,之后通过枚举p2的位置得出答案。由于派驻工兵的过程只涉及一个兵营,因此我们每次枚举p2的位置时只需要对相应队伍的势力值进行O(1)的简单更改即可,总时间复杂度为O(n)。需要注意的是,本题的数据范围中ci的值已经达到了10^9,因此两队的势力值应为long long类型。

评价:本题是一道中规中矩的NOIP普及组第二题,其中设置有“陷阱”,难度不大但拿分并不容易。利用数据范围设置“long long陷阱”是OI题目中较为常见的出题方法,虽然十分常见,但每个“陷阱”中的“冤魂”都不在少数。类似的“陷阱”主要考察选手的审题习惯和对常用数据类型的掌握,这再次告诉我们,一名合格的NOIP选手应当具备扎实的基础知识和良好的审题习惯。

T3 摆渡车(bus)

思路:本题为动态规划问题。我们采用以人为参考对象的方式进行dp,先将所有人员按照到站时间从早到晚排序,设a[i][j]为第i个人等待j分钟的情况下,i及其之后到达的所有人等待时间之和的最小值,易知j∈[0,m),且对于所有j∈[0,m),a[n][j]=j。
我们采取从后向前的方式进行DP,对于状态a[i][j],可分为两种情况:i与i+1同车,或i与i+1不同车。
若i与i+1同车,则i所乘坐的车发车时间必须在i+1到站之后,即须满足j-(t[i+1]-t[i]) >= 0,此时a[i][j]=j+a[i+1][j-(t[i+1]-t[i])];
若i不与i+1同车,则i与i+1所乘坐的两辆车发车间隔必须大于m,即若i+1等待时间为k,须满足k + (t[i+1]-t[i]) - j >= m(条件1),此时a[i][j]=j+a[i+1][k],其中k∈[0,m]且满足条件1。
综合上述两种情况,a[i][j]有多个可能的值,取其中最小的一个作为a[i][j]的值即可。本题的时间复杂度为O(n*m^2)。

另一种可能出现的思路是以t为参考对象进行dp,但由于每个人最多等候时间不会超过m,所以n个人最多等候nm分钟。数据范围中t的上限远大于nm,因此若以t为参考对象,会造成大量时间和空间的浪费,需要优化才能得到满分。

若在考场上无法想出满分算法,可以采用暴力搜索等非满分方法,加上适当的剪枝可拿到30至50分。

评价:本题是一道典型的动态规划问题,但并非经典的模板题,需要选手自行推导动态转移方程。除此之外还需要选手有敏锐的嗅觉,能够在分析题目时想到动态规划的方向,而这需要对算法的熟悉和大量的练习。若不能想出满分算法,暴力搜索对选手的代码能力也有一定的要求。

T4 对称二叉树(tree)

思路:
该题目是一个二叉树的问题,考察结构体(或类)与指针的使用,算法并不复杂,主要考数据结构。

先建立树,我们选择结构体作为节点的数据结构,包含如下几个数据:

struct node//树的节点
{

node* l;//左子节点指针

node* r;//右子节点指针

int weight;//权重

int size;//以此为根的子树节点数

};

容易根据输入数据建立树,但对每个节点,以此节点为根的子树节点数在题目中是重要的,却不能直接得出,我们写一个函数来计算,
由于一个二叉树的节点数等于左右子树节点数之和再加一,我们用int getSize(node root)递归计算。
这就完成了树的建立。

然后,需要检查每个节点的子树是否对称。我们找一个规则进行分治与递归。
容易判断当节点为叶节点则对称;仅一侧有子节点或子节点权值不同时,不对称,难点在于两侧节点权值相同时。
这时,发现当且仅当
1.左子节点右侧子树与右子节点左侧子树对称;
2.左子节点左侧子树与右子节点右侧子树对称;
同时成立时,原树是对称的。每个条件中将需要判断是否对称的两个子树连在一个虚拟的根节点上形成一个二叉树,问题转化为判断
该二叉树是否对称,这就将原问题转化为了两个子问题。用函数int check(node root)递归调用来实现。

最后,检查所有子树,找到对称子树中最大的size即可。

评价:本题作为NOIP普及组的第四题,难度较高,代码量大,对以拿一等奖为目标的普及组选手指导意义不大,但反应了NOIP对选手进一步的能力要求。学有余力的选手可对此题进行研究。

总结:NOIP2018的普及组题目在难度上延续了16、17的出题风格,题目难度梯度较2015年以前更大,第一题更加简单,三四题则更加困难。在出题风格上NOIP2018设计了较多的“陷阱”,即使是简单题,要想拿到满分也并不轻松。这样的出题方式使得对于一等奖选手的实力要求进一步提升,一二题要求选手胆大心细,而第三题则强调对算法思想的理解而非简单地“套模板”,第四题对选手的数据结构知识和结构体、指针的使用提出了一定的要求。除此之外,代码能力的提升是OI永恒的话题,只有具备优秀的代码能力,才能够在不提供提交检查机会的NOIP中拥有稳定的发挥。

你可能感兴趣的:(NOIP2018普及组复赛解题)