• 2022阿里笔试编程题ak口糊(4月15日)


    写代码20分钟ak,但前面选择题基本全忘了(((

    \(A\):签到

    \(B\):对每个非'.'位置下、右、右斜上、右斜下方向分别去check4个是否相同即可

    \(C\):n<=2000,考虑类似树形背包的转移:

    • 对于每个点,其子树之间必没有父子关系,求每个点所有子树之间的答案取min就是最终答案
    • 每个点所有节点的值组成一个集合,这个集合是可以dfs去dp的

    \(a_i<=1000(应该是?), n<=2000\),开数组去存集合不太行,并且求答案需要比较快速。所以对于每个点,开了个set放入已经check完的所有子树,把没check的子树中的点\(x\)在这个set里lower_bound拿到相对近的值的指针,再prev一下,拿到这两个值(如果存在)与x做差取绝对值然后对ans取min,最后按子树顺序把子树插入到check完了的集合里面。(写的好抽象,看代码即可)

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    int v[2005];
    vector<int>G[2005];
    
    int ans = 1e9;
    
    set<int> dfs(int from, int fa) {
        set<int>now;
        for (auto& to : G[from]) {
            if (to == fa)continue;
            auto tmp = dfs(to, from);
            v[from] += v[to];
            for (auto i : tmp) {
                auto p = now.lower_bound(i);
                if (p != now.end()) {
                    ans = min(ans, abs(*p - i));
                }
                if (p != now.begin()) {
                    ans = min(ans, abs(*prev(p) - i));
                }
            }
            for (auto i : tmp)
                now.insert(i);
        }
        now.insert(v[from]);
        return now;
    }
    
    int main()
    {
        int n;
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> v[i];
        }
        for (int i = 1; i < n; i++) {
            int x, y;
            cin >> x >> y;
            G[x].push_back(y);
            G[y].push_back(x);
        }
        dfs(1, 0);
        cout << ans;
        return 0;
    }
    

    总结:暴力即可

  • 相关阅读:
    (转载)openwrt nginx
    *** 竞赛中的各种低级错误,及编程常见错误小结 ***
    信息学奥赛辅导经验谈 & 问题教学法中的学生思维能力培养
    数学&数论的一些题
    信息学竞赛中的一些经典思维 (题)
    从权值线段树到主席树
    浅谈莫队算法
    CSP-S 2019提高组训练 服务器需求
    NOIP2019 PJ 对称二叉树
    NOIP2017 PJ 跳房子 —— 单调队列优化DP
  • 原文地址:https://www.cnblogs.com/ruanbaiQAQ/p/16150842.html
Copyright © 2020-2023  润新知