蓝桥杯备赛小感悟

最近一段时间在备赛第十五届蓝桥杯,自从去年参加十四届蓝桥杯后,心中有些许遗憾,看着其他同学随便拿省二省三,我却没有任何收获,所以想再参加一次。当然,之前没有获奖很大一部分原因是自己根本没有怎么准备,算法也只是刚刚入门而已。

今天回顾了去年蓝桥杯的一道题,没想到费了九牛二虎之力才拿到60%的分数,而且只是第4题A组的题果然是不简单。去年参加考前模拟赛时觉得蓝桥杯不是很难,结果真实难度却远高于模拟难度,现在想想模拟赛应该是所有参赛选手统一的测试,不分组别,所以很可能是C组难度,不知道今年模拟赛难度如何。

题目如下:

想到去年比赛做这个题的时候,连树的数据结构都不会写,只能无奈放弃,上学期开始跟了y总的算法课,学会了很多数据结构的写法,现在做这个题已经有一定能力,思考步骤如下:

  1. 使用邻接表构建树的结构,根据题目信息,存储每个结点的下标和颜色。
  2. dfs遍历每个结点,判断每个结点作为根节点的子树是否为平衡树。

对于第二步,邻接表的遍历复杂度是O(n + m),n为结点个数,m为边数,这道题m和n近似,暂且记为O(n),而题目给的问题规模为2e5左右,明显需要在O(nlogn)以内完成,所以对每个结点子树的判断需要在O(logn)复杂度以内完成。

长时间没有思路后,只能考虑使用暴力方法,记录结点各个子树的不同颜色个数情况,然后将这些记录合并,再加上该结点的颜色信息,再判断以该节点为根节点的子树颜色情况,可以在O(n)复杂度完成,所以估计只能过掉60%样例。由于需要在每个结点处记录颜色信息,每个结点开一个颜色数量数组cnt[N]记录的话占用空间太大,考虑使用hash表,STL中的unordered_map存储。

代码如下:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>

using namespace std;
const int N = 2e5 + 10;
int h[N], e[N], ne[N], idx, color[N];
bool st[N];
int n;
int ans;

void add(int a, int b, int c) {
    e[idx] = b;
    color[b] = c;
    ne[idx] = h[a];
    h[a] = idx++;
}

unordered_map<int, int> dfs(int u) {
    st[u] = true;
    unordered_map<int, int> cnt;
    for (int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if (!st[j]) {
            unordered_map<int, int> ct = dfs(j);
            // 合并
            for (auto num : ct)
                cnt[num.first] += num.second;
        }
    }
    // 记录颜色
    cnt[color[u]]++;
    int base = 0;
    for (auto it : cnt) {
        if (base == 0)
            base = it.second;
        else {
            if (base != it.second) return cnt;
        }
    }
    ans++;
    return cnt;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    memset(h, -1, sizeof h);
    cin >> n;
    int C, F;
    for (int i = 1; i <= n; i ++ ) {
        cin >> C >> F;
        add(F, i, C);
    }
    
    dfs(1);
    cout << ans;
    return 0;
}

小感悟:

做完以后了解了满分解法,需要使用启发式合并思想来做,但是有一定难度,对于目前来说学习的性价比不高。下个月蓝桥杯省赛,不要死磕地想要过掉所有样例,拿40%~60%分数即可,算算也有七八十分,应该能接近省一。学了一段时间的算法,感觉有很多遗憾,遗憾自己为什么没有早点接触良好的算法学习资源(y总yyds),提前学习算法知识,如今已是大三老狗。不过也无所谓了,想想现在的能力比去年强了很多,学到了许多算法知识,体会到算法AC的乐趣,这样来说也算没有太多遗憾。希望今年蓝桥杯能取得好成绩吧,至少拿个奖就好,继续加油。

  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值