9.26 腾讯后台笔试题解

第一题:质数 + 贪心
第二题AC:
#include <bits/stdc++.h>
using namespace std;
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int i = 0; i < n; ++i)
            cin >> a[i];

        vector<int> v(n, -1);
        int ans = 0;
        for (int start = 0; start < n; ++start) {
            int sum = 0;
            int cur = start;
            if (v[cur] > sum) continue;
            // 之前跳过了肯定是不用看了
            while (cur < n) {
                sum += a[cur];
                if (v[cur] > sum) {
                    break;
                }
                v[cur] = sum;
                cur += a[cur];
            }
            ans = max(ans, sum);
        }
        cout << ans << endl;

    }

    return 0;
}

第三题AC:栈
#include<bits/stdc++.h>
using namespace std;
inline bool isDigit(char c) {
    return c <= '9' && c >= '0';
}
inline bool great(char a, char b) {
    int p, q;
    switch(a) {
        case '+' : p = 0; break;
        case 'x' : p = 1; break;
        case '@' : p = 2; break;
    }
    switch(b) {
        case '+' : q = 0; break;
        case 'x' : q = 1; break;
        case '@' : q = 2; break;
    }
    return p > q;

}

// 看样子第一题有坑啊,这居然都发公告了
long long cal(long long a, long long b, char o) {
    switch(o) {
        case '+' : return a + b;
        case 'x' : return a * b;
        case '@' : return a | (a + b);
    }
    return -1;
}
int main() {
    // 还是首先认真审题好吧
    // + 加法
    // x 乘法
    // 新定义运算是吧
    // a @ b = a | (a + b)
    // 优先级 @ > x > +
    // 同优先级是从左到右
    // 开long long
    // 注意是没有括号的
    string s;
    cin >> s;
    // 数值直接压栈,然后看操作符号,如果栈顶的优先级比自己低,压栈,比自己高,弹出
    stack<char> oper;
    stack<long long> nums;
    int n = s.length();
    for (int i = 0; i < n; ) {
        char c = s[i];
        if (isDigit(c)) {
            long long num = c - '0';
            i++;
            c = s[i];
            while (isDigit(c) && i < n) {
                num = num * 10LL + (c - '0');
                i++;
                c = s[i];
            }
            nums.push(num);
        } else {
            // 说明是操作符,看情况来了
            i++; // 别忘了这一步

            // 应该先验证正确性的好吧
            while (true) {
                if (oper.empty()) {
                    oper.push(c);
                    break;
                } else {
                    char o = oper.top();
                    // 如果c的优先级比栈顶高,压栈
                    if (great(c, o)) {
                        oper.push(c);
                        break;
                    } else {
                        oper.pop();
                        long long b = nums.top();
                        nums.pop();
                        long long a = nums.top();
                        nums.pop();
                        long long t = cal(a, b, o);
                        nums.push(t);

                    }
                }
            }
        }
    }
    while (!oper.empty()) {
        char o = oper.top();
        oper.pop();
        long long b = nums.top();
        nums.pop();
        long long a = nums.top();
        nums.pop();
        long long t = cal(a, b, o);
        nums.push(t);
    }
    cout << nums.top();

    return 0;
}

第四题AC:二叉树
#include <bits/stdc++.h>
using namespace std;

 struct TreeNode {
 	int val;
 	struct TreeNode *left;
 	struct TreeNode *right;
 	TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
  };


class Solution {
private:
    // 应该还要记录左右信息, 0 左 1 右
    // 不用,反而麻烦,之后判断一下就是
    unordered_map<int, TreeNode*> pa;

    unordered_map<int, TreeNode*> node;
private:
    TreeNode* lca(TreeNode* root, TreeNode* p, TreeNode* q) {
        // 如果在一左一右找到了结点,那么就是这个根结点咯,如果不是
        if (root == nullptr || root == p || root == q) return root;
        TreeNode* left = lca(root->left , p, q);
        TreeNode* right = lca(root->right, p , q);
        if (!left && !right) return nullptr;
        if (left && !right) return left;
        if (!left && right) return right;
        else return root;
    }
    // 建立父亲结点hash和自己的hash,之后动态改变,可能稍微有点麻烦
    void dfs(TreeNode* root) {
        node[root->val] = root;
        if (root->left) {
            pa[root->left->val] = root;
            dfs(root->left);
        }
        if (root->right) {
            pa[root->right->val] = root;
            dfs(root->right);
        }
    }

public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param root TreeNode类 指向量子树的根
     * @param b int整型vector<vector<>> 表示每次交换的两个子树
     * @return TreeNode类
     */
    TreeNode* solve(TreeNode* root, vector<vector<int> >& b) {
        // write code here
        // 这道题一定要小心审题,看样子是有诈的
        // 某些时刻会有两子树交换位置,
        // 假设x和y交换律位置,x的父亲fa[x], y 父亲fa[y]
        // x 与 fa[x] 边断开, y 与 fa[y] 间的边会断开
        // 然后 x 连 fa[y], 同理
        // !!!!!!!!!!! 可能有不合法的情况,这种情况忽略此次交换,那么还得有机制能够达到这种方式
        // 这道题抽象为找最临近父节点的问题就是了
        // 树的编号是1 - n 的整数并且互不相同, 找到相应的结点也是个问题,unoreder_map好啦,
        // 先遍历一遍树并且建立树,之后就lucky了
        dfs(root);
        for (const vector<int>& a : b) {
            int p = a[0], q = a[1];
            TreeNode* tp = node[p];
            TreeNode* tq = node[q];
            TreeNode* lcap = lca(root, tp, tq);
            // cout << lcap->val;
            // 不合法食大便啦
            if (lcap == tq || lcap == tp)
                continue;
            TreeNode* pp = pa[p];
            TreeNode* pq = pa[q];
            TreeNode* pl = pp->left;
            TreeNode* pr = pp->right;
            TreeNode* ql = pq->left;
            TreeNode* qr = pq->right;
            
            if (pl == tp) {
                pp->left = tq;
            } else if (pr == tp) {
                pp->right = tq;
            }
            pa[q] = pp;
            if (ql == tq) {
                pq->left = tp;
            } else if (qr == tq) {
                pq->right = tp;
            }
            pa[p] = pq;
        }
        return root;
    }
};

int main() {
    TreeNode* p1= new TreeNode(1);
    TreeNode* p2= new TreeNode(2);
    TreeNode* p3= new TreeNode(3);
    TreeNode* p4= new TreeNode(4);
    TreeNode* p5= new TreeNode(5);
    TreeNode* p6= new TreeNode(6);
    TreeNode* p7= new TreeNode(7);

    p1->left = p2;
    p1->right = p3;
    p2->left = p4;
    p2->right = p5;
    p3->left = p6;
    p3->right = p7;
    vector<vector<int>> vec;
    vec.push_back({1, 2});
    vec.push_back({2, 3});
    Solution().solve(p1, vec);

}

第五题:图论,没来得及做


#腾讯##笔经#
全部评论
***了,做完234题再做,第1题只剩10分钟,虽然想出来怎么做了,但是快马加鞭也还是差点点,****。
点赞 回复 分享
发布于 2021-09-26 22:08

相关推荐

11-03 14:38
重庆大学 Java
AAA求offer教程:我手都抬起来了又揣裤兜了
点赞 评论 收藏
分享
2 3 评论
分享
牛客网
牛客企业服务