LeetCode第327场周赛

文章介绍了四道LeetCode周赛中的编程题目,包括正整数和负整数的最大计数、执行K次操作后的最大分数、使字符串总不同字符的数目相等以及过桥的时间问题。每道题都提供了思路和C++代码实现,涉及模拟、优先队列等算法思想。
摘要由CSDN通过智能技术生成

2023.1.8LeetCode第327场周赛

2529. 正整数和负整数的最大计数

思路

根据题意模拟即可

代码

class Solution {
public:
    int maximumCount(vector<int>& nums) {
        int a = 0, b = 0;
        for (int x : nums) {
            if (x > 0)
                a ++ ;
            if (x < 0)
                b ++ ;
        }
        return max(a, b);
    }
};

2530. 执行 K 次操作后的最大分数

思路

使用优先队列,每次选出最大的nums[i]累加到结果中

代码

class Solution {
public:
    typedef long long ll;
    
    long long maxKelements(vector<int>& nums, int k) {
        priority_queue<ll> q;
        int n = nums.size();
        for (int i = 0; i < n; i ++ ) {
            q.push(nums[i]);
        }
        ll ans = 0;
        while (k) {
            auto t = q.top();
            q.pop();
            ans += t;
            q.push((t + 2) / 3);
            k -- ;
        }
        return ans;
    }
};

2531. 使字符串总不同字符的数目相等

思路

记录每个字符出现的次数
枚举每个可能交换的组合

代码

class Solution {
public:
    bool isItPossible(string word1, string word2) {
        vector<int> a(26), b(26);
        for (auto c : word1) a[c - 'a'] ++ ;
        for (auto c : word2) b[c - 'a'] ++ ;
        int n1 = 0, n2 = 0;
        for (int i = 0; i < 26; i ++ ) {
            if (a[i] > 0) n1 ++ ;
            if (b[i] > 0) n2 ++ ;
        }
        for (int i = 0; i < 26; i ++ )
            if (a[i] > 0)
                for (int j = 0; j < 26; j ++ )
                    if (b[j] > 0) {
                        if (i == j) { //字符相等时,不同字符的数目要相等
                            if (n1 == n2) return true;
                        }
                        else {
                        	// 否则模拟最后的结果
                            int c1 = n1, c2 = n2;
                            if (a[i] - 1 == 0) c1 -- ;
                            if (a[j] == 0) c1 ++ ;
                            if (b[j] - 1 == 0) c2 -- ;
                            if (b[i] == 0) c2 ++ ;
                            if (c1 == c2)
                                return true;
                        }
                    }
        return false;
    }
};

2532. 过桥的时间

思路

使用四个堆进行模拟,等待过桥的工人根据题意判断优先级,正在装卸货的工人根据工作完成的时间判断优先级
当还有货物或者右边有人时,需要进行操作,每次从队列里取出优先级最高的工人:

  1. 搬起和放下的工人当前时刻已完成工作,需要加入等待队列
  2. 先让右边的工人过河,过河后进入正在卸货的队列
  3. 当还有货要搬且左边有人时,左边过河,再进入装货的队列
  4. 否则没有人过河,时间需要前进到第一个完成工作的工人的时刻

代码

class Solution {
public:
    typedef pair<int, int> PII;

    struct Node {
        int l, r, ol, ne, idx;
        bool operator < (const Node &a) const { //效率低的优先级高
            if (l + r == a.l + a.r) {
                return idx < a.idx;
            }
            return l + r < a.l + a.r;
        }
    };
    
    int findCrossingTime(int n, int k, vector<vector<int>>& time) {
        priority_queue<Node> L, R; //左右正在等待过桥的
        priority_queue<PII, vector<PII>, greater<PII>> waitL, waitR; //左右正在卸货的
        for (int i = 0; i < k; i ++ ) {
            L.push({time[i][0], time[i][2], time[i][1], time[i][3], i});
        }
        int ans = 0;
        while (n || waitR.size() || R.size()) {
            //先将卸完货的加入等待队列
            while (waitR.size() && ans >= waitR.top().first) {
                auto t = waitR.top();
                waitR.pop();
                int i = t.second;
                R.push({time[i][0], time[i][2], time[i][1], time[i][3], i});
            }
            while (waitL.size() && ans >= waitL.top().first) {
                auto t = waitL.top();
                waitL.pop();
                int i = t.second;
                L.push({time[i][0], time[i][2], time[i][1], time[i][3], i});
            }
            //优先让右边的过桥
            if (R.size()) {
                auto t = R.top();
                R.pop();
                ans += t.r;
                waitL.push({ans + t.ne, t.idx});
            }
            else if (L.size() && n) { //如果还有货要搬且有工人
                auto t = L.top();
                L.pop();
                n -- ;
                ans += t.l;
                waitR.push({ans + t.ol, t.idx});
            }
            else { //否则需要等待最先搬起/放下货的工人完成
                int x = 1e9;
                if (waitR.size()) x = min(x, waitR.top().first);
                if (waitL.size()) x = min(x, waitL.top().first);
                ans = max(ans, x);
            }
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值