Leetcode第230场周赛

A题:5689. 统计匹配检索规则的物品数量

  • 纯模拟
class Solution {
public:
    int countMatches(vector<vector<string>>& items, string ruleKey, string ruleValue){
        int res = 0;
        for(auto &x : items){
            if(ruleKey == "type"){
                res += ruleValue == x[0];
            }else if(ruleKey == "color"){
                res += ruleValue == x[1];
            }else{
                res += ruleValue == x[2];
            }
        }
        return res;
    }
};

B题:1774. 最接近目标价格的甜点成本

  • DFS或者是4进制枚举,只需要把所有的情况枚举出来就好了,或者是完全背包也可以做
class Solution {
public:
    int closestCost(vector<int>& baseCosts, vector<int>& toppingCosts, int target) {
        
        int n = baseCosts.size(),m = toppingCosts.size();
        
        int res = 1e9;

        for(int i = 0;i < n;i ++){
            for(int j = 0;j < 1 << m * 2;j ++){
                int t = baseCosts[i];
                for(int k = 0;k < m;k ++){
                    int wei = j >> k * 2 & 3;
                    if(wei == 3){
                        t = 1e9;
                        break;
                    }
                    t += wei * toppingCosts[k];
                }
                if(abs(t - target) < abs(res - target) || abs(t - target) == abs(res - target) && t < res){
                    res = t;
                }
            }

        }
       return res; 
    }
};

C题:1775. 通过最少操作次数使数组的和相等

  • 能够组成的数字一定是在m 到 6 * n之间(n < m),然后枚举m 到 n * 6 之间的数字,如果是sum > 要枚举的数字,那么我们首先就先用6,然后是5...,否则相反,还有要上取整。
class Solution {
public:

    int work(vector<int>v,int x){
        int sum = 0;
        for(int i = 1;i < 7;i ++){
            sum += i * v[i];
        }
        int res = 0;
        if(sum > x){
            int cha = sum - x;
            for(int i = 6;i > 1;i --){
                int t = i - 1;
                if(t * v[i] >= cha){
                    res += (cha + t - 1) / t;
                    break;
                }else{
                    cha -= t * v[i];
                    res += v[i];
                }
            }
        }else{
            int cha = x - sum;
            for(int i = 1;i < 7;i ++){
                int t = 6 - i;
                if(t * v[i] >= cha){
                    res += (cha + t - 1) / t;
                    break;
                }else{
                    cha -= t * v[i];
                    res += v[i];
                }
            }

        }
        return res;
    }

    int minOperations(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size(),m = nums2.size();
        if(n > m){
            return minOperations(nums2,nums1);
        }

        vector<int>v1(7),v2(7);
        int res = 1e9;
        if(n * 6 < m) return -1;

        for(auto &x :nums1){
            v1[x] ++;
        }
        for(auto &x : nums2){
            v2[x]++;
        }

        for(int i = m;i <= n * 6;i ++){
            res = min(res,work(v1,i) + work(v2,i));
        }
        return res;
    }
};

D题:车队 II

class Solution {
public:
    //这道题必须想清楚一点,那就是如果ans[i]有正值,那么一定是cars[i]和某个cars[j](j>i且speed[j]<speed[i])发生碰撞
    //相撞之后,所谓的融合,其实可以理解为cars[i]消失了,cars[j]状态不变
    //所以我们只关注一辆车右边,不关注其左边,它的左边对它没有任何影响。可以考虑从右往左遍历
    vector<double> getCollisionTimes(vector<vector<int>>& cars) {
        vector<double>ans(cars.size());
        //设立一个单调栈,栈底最慢,栈顶最快
        stack<int>S;
        for(int i=cars.size()-1;i>=0;i--){
            while(S.size()){
                //如果栈顶比我快,我追不上它,可以考虑等它消失之后我去撞它前面的,所以将它pop
                if(cars[S.top()][1]>=cars[i][1])S.pop();
                //如果栈顶比我慢,我就决定去碰它了
                else{
                    //如果它不会消失,那我肯定能碰它,break
                    if(ans[S.top()]<0)break;
                    //如果它会消失,我需要计算一下在它消失之前能否追上它
                    double d=ans[S.top()]*(cars[i][1]-cars[S.top()][1]);
                    //能追上,那我肯定碰它,break
                    if(d>cars[S.top()][0]-cars[i][0])break;
                    //追不上,那算了,追它前面的车
                    else S.pop();
                }
            }
            if(S.empty())ans[i]=-1;
            else{
                //相对距离除以相对速度
                double t=double(cars[S.top()][0]-cars[i][0])/double(cars[i][1]-cars[S.top()][1]);
                ans[i]=t;
            }
            S.push(i);
        }
        return ans;
    }
};

作者:oldyan
链接:https://leetcode-cn.com/problems/car-fleet-ii/solution/cdan-diao-zhan-by-oldyan-ij4k/
posted @ 2021-03-01 16:14  遇见生活  阅读(100)  评论(0编辑  收藏  举报