21蓝桥国赛总结

  1. 篇头的话
    去年开始至今也打了不少比赛了,每场比赛都有遗憾,但这也意味着每场比赛都有收获。所以我决定从这场比赛开始,对每一场比赛做一下总结,一是留给自己看,作为备忘;二是可以跟大家一起分享经验。

  2. 总体印象
    奇特的是国赛相较省赛来讲更加简单,但是我的表现却比省赛更差。
    省赛的题目虽然困难,但是我做题的时候目的性是很强的,只为拿去更高的分数,所以对于后面的一些大题就不去考虑时间复杂度的问题,只是使用尽可能简便的方法暴力。这一策略对我的成绩应当是有正向作用的。
    但是在国赛中,我却总想着搞个大新闻,在括号翻转那道题上耗费了非常非常多的时间。而且最后也没有求解出来,这直接导致我最后三道大体一分未拿,损失巨大!
    日后当引以为戒!!

  3. 填空题
    填空题阶段做的还算顺利。
    A题带宽,我直接200 / 8得了25填了上去。
    比赛结束后看到有人说带宽的进制是10进制,所以答案不是简单的25。但是如果按照这种思路的话,答案就不是题目描述中的整数了,所以我感觉存疑。
    我对于这道题的求解是满意的,因为比赛中本就没必要纠结于一个记忆型的题目,不管哪种做法正确,在比赛中都是一个概率问题。只要没有耗费太多时间,没有因为纠结而影响后面的题目就是胜利。

    B题纯质数,不满意。
    因为我第一遍写素数筛竟然写错了,这是完全不应该出现的错误。而且我在写素数筛的时候发现,我对于线性筛的写法不确定,虽然使用普通筛法也不会影响该题的解答,但是放到其他题目上就会出问题了。

    C题完全日期,还算满意。
    满意的是我对日期题的谨慎态度,私以为日期题是极有可能因为小细节出问题而马失前蹄的,所以谨慎一点,耗费一点儿时间多检查几遍是值得的。
    不满意的地方是,我在处理闰年2月的特殊情况时,是在天数循环跑完了默认的28的for循环后,再加一个if,但是在if中我又对天数进行了加加,导致参与运算的天数的值是30而非29。尽管在随后的检查中发现了问题,而且这个Bug也不会影响结果,但是这是绝不应该出现的错误。

    D题最小权值,还算满意。
    不好的地方是,我一开始读错了题意。一开始看表达式时,并没有注意到表达式中有左右子树的权值,还以为这个值只与左右子树的节点个数有关,而与子树结构无关。所以一上去就写了一个for循环,循环左子树可能的节点个数,取二叉树权值最小值。(这个写法还写错了,因为根节点需要占一个结点,所以左右子树节点和应当是2020,我却用了2021)所幸后来感觉题目太过简单,怀疑是不是自己读错了题,细读之后,得到了正确的题意。
    好的地方是,得到立刻就想到了做法,没有在思考上耗费太多的时间,代码比较简单,回来后写了一下。

#include 
#include 
#include 
using namespace std;

typedef long long ll;
const int N = 3000;
ll dp[N];

int main()
{
    memset(dp, 0x3f, sizeof dp);
    dp[0] = 0;
    for (int i = 1; i <= 2021; i++)
    {
        for (int l = 0; l < i; l++)
        {
            int r = i - l - 1;
            ll nowans = 1 + 2 * dp[l] + 3 * dp[r] + l * l * r;
            dp[i] = min(dp[i], nowans);
        }
    }
    cout << dp[2021] << endl;
    system("pause");
    return 0;
}
// 输出:2653631372
  1. 编程题
    非常不满意。

    E题大写,名副其实的签到题。
    个人认为这道题出现的国赛有点不太适宜,哪怕稍微难点儿呢?难道是因为太多人吐槽省赛难度,主办方有意为之?

    F题123,做的还算满意。
    我是用分块搞了个前缀和做的。
    b[i]表示在数列中第一个i出现时的前缀和。这个等差序列求和公式很容易求出来。
    对于给定位置的前缀和,我的求法是:上一个1之前的前缀和 + 从上一个1到当前位置的前缀和。

    G题异或变换,非常不满意。
    这个很容易联想到它的变化是由周期的,然后对周期取模。一开始自己打印测试找周期,没找到规律就暴力了。
    但是暴力写的非常没有水平!!第一点,模拟的过程中我就直接使用了字符串,而没有使用bitset。实际上应当使用bitset,只要左移一位再和当前异或即可,耗时会大大减小。第二点,既然已经想到取模了,那就应该在模拟的过程中判断是否和初始串相同,如果相同,取模。但我没有做判断,也没有取模。

    H题二进制问题,非常不满意。
    根本没有看,连暴力也没写,直接爆零。

    I题翻转括号序列,本次比赛的最大败笔!
    读完题后,思路立马就成型了,线段是+懒标。写起来也很顺利,建树、修改都顺利完工,但是在查询上遇到了困难。
    对于一个合法的括号序列,应该满足的条件应当是左括号数和右括号数相同,并且在开始至中途的任意一段括号序列中都不能出现右括号数比左括号数多的情况。
    就是第二个条件把我难住了,因为这个条件无法二分判断,那就只能以O(n)的时间复杂度判断,线段树建的就没意义了。比赛结束后,我在网上看到一个思路,顿时感觉茅塞顿开。
    这道题所给我的教训不是思路上的问题,有题目想不出思路很正常,但是我犯得最大错误是:在没有保证其他题目拿到暴力分的前提下,还在死扣这道题。结果导致后三道题的暴力都没写,直接爆零。

  2. 总结
    经验教训如下:

    1. OI竞赛,最低限度要保证所有编程题的暴力分拿到手,没有达到这一点之前不能死扣某道题。
    2. 积极暴力。不能以为最坏时间复杂度没有得到改善就不对暴力进行优化,相反,应当尽自己一切可能的对暴力写法进行优化,哪怕是常数系数的优化,甚至常数项的优化。

你可能感兴趣的:(随笔,算法)