8.10 zoom 笔试题解心得

T1 求树的权值

告诉你一棵树的结点分为蓝色和红色,一个结点的权值定义为:从根结点到该结点路径上的红蓝结点个数之差的绝对值。

求整棵树的权值之和。

#include <bits/stdc++.h>

using namespace std;

int n; 
string color;
vector<vector<int>> g;
long long ans = 0;

void dfs(int x, int bl, int red, int from) {
    if (color[x] == 'R') ++red;
    else ++bl;
    ans += abs(bl-red);
    for (auto to : g[x]) {
        if (to != from) {
            dfs(to, bl, red, x);
        }
    }
}

int main() {
    cin >> n;
    cin >> color;
    g.resize(n);
    int u, v;
    for (int i = 0; i < n-1; ++i) {
        cin >> u >> v;
        g[u-1].push_back(v-1);
        g[v-1].push_back(u-1);
    }
    dfs(0, 0, 0, 0);
    cout << ans << endl;
    return 0;
}


T2 给用户推荐股票的数目

每个用户都有喜欢的股票,如果一个用户 A 喜欢股票 a, b;用户 B 喜欢 b, c。那么相当于在股票 a 和 b, b 和 c 之间建立了两条边,如果用户 C 喜欢 c,那么系统会给 c 推荐股票 a 和 b。

求给用户 x 推荐股票的数目(不包含自己喜欢的股票)

#include <bits/stdc++.h>

using namespace std;

#define maxn 50005

struct UF {
    int f[maxn+5], cnt[maxn+5];

    UF(int n) {
        for (int i = 0; i <=n; ++i) {
            f[i] = i; cnt[i] = 1;
        }
    }
    int getp(int x) { return f[x] == x ? f[x] : f[x] = getp(f[x]); }
    void add(int x, int y) {
        int px = getp(x), py = getp(y);
        if (cnt[px] < cnt[py]) swap(px, py);
        if (px != py) {
            f[px] = py;
            cnt[py] += cnt[px];
        }
    }
};

int main() {
    int q; cin >> q;
    int n, op, no = 0;
    string name, share;
    unordered_map<string, set<int>> users;
    unordered_map<string, int> shareid;
    UF uf(maxn);
    while (q--) {
        cin >> op >> name;
        if (op == 1) {
            cin >> n;
            vector<int> ids(n);
            for (int i = 0; i < n; ++i) {
                cin >> share;
                if (!shareid.count(share)) shareid[share] = no++;
                ids[i] = shareid[share];
                users[name].insert(ids[i]);
            }
            for (int i = 0; i < n; ++i) {
                for (int j = i+1; j < n; ++j) {
                    uf.add(ids[i], ids[j]);
                }
            }
        } else {
            if (users[name].empty()) {
                cout << "error" << endl;
                continue;
            }
            int inc = 0;
            set<int> pp;
            for (auto us : users[name]) {
                int p = uf.getp(us);
                if (pp.count(p)) continue;
                pp.insert(p);
                auto cnt = uf.cnt[p];
                inc += cnt;
                for (auto us2 : users[name]) {
                    if (uf.getp(us) == uf.getp(us2)) --inc;
                }
            }
            cout << inc << endl;
        }
    }
    return 0;
}


#校招##做完zoom2023秋招笔试,人麻了#
全部评论
投的前端 感觉算法难度还好
5 回复 分享
发布于 2022-08-10 20:13
java一道没写出来
4 回复 分享
发布于 2022-08-10 20:26
寄,两道都是图,太难了,一道都没做出来
3 回复 分享
发布于 2022-08-10 20:26
第一题93 不知道哪错了,第二题超时了 草
2 回复 分享
发布于 2022-08-10 20:37
第一道dfs过了,第二道想到并查集但是不会😅
2 回复 分享
发布于 2022-08-10 20:33
好难😥寄
2 回复 分享
发布于 2022-08-10 20:21
算法感觉好难
2 回复 分享
发布于 2022-08-10 20:12
这么快就写完啦?
2 回复 分享
发布于 2022-08-10 20:11
大佬带带我😜
1 回复 分享
发布于 2022-08-11 01:21
人与人差距怎么这么大😃
1 回复 分享
发布于 2022-08-10 20:44
第二题只过了百分之十不知道哪里错了
1 回复 分享
发布于 2022-08-10 20:41
ac一道
1 回复 分享
发布于 2022-08-10 20:33
难,真得难,第一题建邻接表DFS暴力搜索只能过46%,第二题两分钟前想到可以用并查集做,但是针对字符串的并查集没写过。。。。来不及了。。。
1 回复 分享
发布于 2022-08-10 20:29
奇安信内推码:NTAISr3 官网投递地址:https://campus.qianxin.com/campus/jobSearch?jobTag=all
点赞 回复 分享
发布于 2022-08-10 23:43
您好 求教一下在执行register操作时,最后两层for循环改成一层for循环可以吗 我不太理解两层for循环的意义 我跟舍友讨论了半天没想明白,烦请您解惑!
点赞 回复 分享
发布于 2022-08-10 23:32
看着这间接的写法 眼泪流下来
点赞 回复 分享
发布于 2022-08-10 23:08
求问为什么第一题dfs没有返回条件,不太会图的题
点赞 回复 分享
发布于 2022-08-10 21:09
和java的输入输出比起来,c++简直优雅
点赞 回复 分享
发布于 2022-08-10 20:58
个人思考可以建多叉树,输入u,v时,双方互为对方的孩子节点,最后从根节点遍历时,加个访问数组,仅计算未访问的孩子节点。(实在是看不懂并查集了)
点赞 回复 分享
发布于 2022-08-10 20:56
是我太菜了
点赞 回复 分享
发布于 2022-08-10 20:43

相关推荐

05-09 13:22
门头沟学院 Java
点赞 评论 收藏
分享
评论
18
72
分享

创作者周榜

更多
牛客网
牛客企业服务