LCP春季赛个人赛前3题题解

- 本人的LeetCode账号:魔术师的徒弟,欢迎关注获取每日一题题解,快来一起刷题呀~

一、宝石补给

LCP 50. 宝石补给

  简单模拟即可。

class Solution {
public:
    int giveGem(vector<int>& gem, vector<vector<int>>& operations) 
    {
        for (auto& op : operations)
        {
            int x = op[0], y = op[1];
            int give = gem[x] / 2;
            gem[x] -= give;
            gem[y] += give;
        }
        int mymax = *max_element(gem.begin(), gem.end());
        int mymin = *min_element(gem.begin(), gem.end());
        return mymax - mymin;
    }
};

二、烹饪料理

LCP 51. 烹饪料理

  注意到数据范围非常小且每份料理我们只能制作一次,所以可以进行一个状态压缩,我们以菜的个数个二进制表示状态,二进制位为1表示这道菜要做,为0表示不做,每次把满意度、需要的食材、饱腹感计算一下,如果需要的食材和饱腹感能满足要求,计算满意度的最大值、

class Solution {
public:
    int perfectMenu(vector<int>& materials, vector<vector<int>>& cookbooks, vector<vector<int>>& attribute, int limit) 
    {
        int n1 = attribute.size();
        // 用一个n1位的二进制数表示每个菜做或不作
        int ret = -1;
        for (int i = 1; i < (1 << n1); ++i)
        {
            int check = i;
            int need0 = 0, need1 = 0, need2 = 0, need3 = 0, need4 = 0;
            int taste = 0;
            int full = 0;
            for (int j = 0; j < n1; ++j)
            {
                int flag = check >> j & 1;
                if (flag == 0) continue;
                need0 += cookbooks[j][0];
                need1 += cookbooks[j][1];
                need2 += cookbooks[j][2];
                need3 += cookbooks[j][3];
                need4 += cookbooks[j][4];
                taste += attribute[j][0];
                full += attribute[j][1];
            }
            if (need0 <= materials[0] && need1 <= materials[1] && need2 <= materials[2] && need3 <= materials[3] 
                && need4 <= materials[4] && full >= limit)
            {
                ret = max(ret, taste);
            }
        }
        return ret;
    }
};

三、二叉搜索树染色

LCP 52. 二叉搜索树染色

  注意到二叉树的染色仅与其最终的颜色有关,所以我们可以先遍历一遍二叉搜索树,用一个有序集合来维护它,然后倒序遍历操作数组,利用有序集合setlower_bound找到有序集合中大于等于左边界最小数,一直删除到左边界即可,删除过程中,如果此次染色为红色,则红色结点+1,最后返回红色结点的数量。

class Solution {
public:
    // 染色仅由最后一次决定
    set<int> myset;
    int getNumber(TreeNode* root, vector<vector<int>>& ops) 
    {
        Inorder(root);
        int res = 0;
        for (int i = ops.size() - 1; i >= 0; --i)
        {
            if (myset.empty()) break;
            auto it = myset.lower_bound(ops[i][1]);
            while (it != myset.end()
             && (*it) <= ops[i][2])
             {
                 it = myset.erase(it);
                 if (ops[i][0] == 1)
                 ++res;
             }
        }
        return res;
    }
    void Inorder(TreeNode* root)
    {
        if (root == nullptr)
        {
            return;
        }
        Inorder(root->left);
        myset.insert(root->val);
        Inorder(root->right);
    }
};

四、扯淡

  该说发挥的好吗,,,第三题没想到这种巧妙地解法套的线段树板子。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值