zoukankan      html  css  js  c++  java
  • LeetCode第243场周赛

    第一题 1880. 检查某单词是否等于两单词之和

    题目链接:1880. 检查某单词是否等于两单词之和

    • 逐位计算单词之和即可
    class Solution {
    public:
        int count(string s) {
            int ans = 0;
            for(const auto& c: s) {
                ans = ans * 10 + c - 'a';
            }
            return ans;
        }
        
        bool isSumEqual(string firstWord, string secondWord, string targetWord) {
            return count(firstWord) + count(secondWord) == count(targetWord);
        }
    };
    

    第二题 1881. 插入后的最大值

    题目链接:1881. 插入后的最大值

    • 如果n是正数,则从左往右找到第一个比x小的数,把x插入到这个数的左边
    • 如果n是负数,则从左往右找到第一个比x大的数,把x插入到这个数的右边
    class Solution {
    public:
        string maxValue(string n, int x) {
            if(n[0] != '-') {
                int i = 0;
                while(i < n.size() && n[i] - '0' >= x) {
                    ++i;
                }
                if(i == n.size()) {
                    return n + to_string(x);
                } else {
                    return n.substr(0, i) + to_string(x) + n.substr(i);
                }
            } else {
                int i = 1;
                while(i < n.size() && n[i] - '0' <= x) {
                    ++i;
                }
                if(i == n.size()) {
                    return n + to_string(x);
                } else {
                    return n.substr(0, i) + to_string(x) + n.substr(i);
                }
            }
        }
    };
    

    第三题 1882. 使用服务器处理任务

    题目链接:1882. 使用服务器处理任务

    • 根据题目的规则,我们把服务器分为“空闲的服务器”idle servers和“忙碌的服务器”busy servers
    • 每次一个新的任务到来,都会选择一个“最适合当前任务”的服务器来运行任务
    • 新任务到来时:
      • 如果当前有空闲的服务器,则在空闲的服务器里选择权重最小的服务器运行,如果权重都一样,则选择下标最小的服务器
      • 如果没有空闲的服务器,则会等待忙碌的服务器里第一个运行完任务(变为空闲)的服务器去运行任务;如果多个服务器同时变为空闲,则按照空闲的服务器的排序规则进行选择
    • 根据这个思想,很容易想到用两个优先级队列去维护空闲的服务器is忙碌的服务器bs,两个优先级队列有不同的排序规则
    • 初始时,所有的服务器都是空闲的服务器
    • 因为需要记录忙碌的服务器的完成时间,因此我们构建的服务器结构体包含时间权重下标三个数据成员
    • 对于每个任务,都会从“空闲的服务器”里选择“最合适”的服务器运行任务,这时就把这个服务器从is弹出,加入到bs
    • 如果对于当前任务,没有空闲的服务器,那么就会等忙碌的服务器中出现空闲的服务器,然后再运行任务
    class Solution {
    private:
        int n, m;
        vector<int> ans;
        
        struct server {
            int time, weight, index;
            server(int t, int w, int i) {
                time = t;
                weight = w;
                index = i;
            }
        };
        
    public:
        struct busyServer {                                    // “忙碌的服务器”的优先队列的排序规则
            bool operator() (server a, server b) {
                if(a.time != b.time) {                         
                    return a.time > b.time;
                }
                if(a.weight != b.weight) {
                    return a.weight > b.weight;
                }
                return a.index > b.index;
            }
        };
        
        struct idleServer {                                   // “空闲的服务器”的优先队列的排序规则
            bool operator() (server a, server b) {
                if(a.weight != b.weight) {
                    return a.weight > b.weight;
                }
                return a.index > b.index;
            }
        };
        
        vector<int> assignTasks(vector<int>& servers, vector<int>& tasks) {
            n = servers.size();
            m = tasks.size();
            priority_queue<server, vector<server>, busyServer> bs;
            priority_queue<server, vector<server>, idleServer> is;
            for(int i = 0; i < n; ++i) {
                is.push(server(0, servers[i], i));
            }
            for(int i = 0; i < m; ++i) {
                while(!bs.empty() && bs.top().time <= i) {         // 当前是第 i 秒,忙碌的服务器的优先队列中可能有服务器已经运行完成了,需要弹出堆
                    is.push(bs.top());
                    bs.pop();
                }
                if(!is.empty()) {                      // 如果有空闲的服务器,则在 is 堆里选择服务器运行,并把服务器加入到 bs 中
                    auto t = is.top();
                    is.pop();
                    ans.push_back(t.index);
                    bs.push(server(i + tasks[i], t.weight, t.index));
                } else {                  // 如果没有空闲的服务器,则等待忙碌的服务器中最先运行完成的服务器,在最先完成的服务器中选择服务器运行任务
                    auto t = bs.top();
                    bs.pop();
                    ans.push_back(t.index);
                    bs.push(server(t.time + tasks[i], t.weight, t.index));
                }
            }
            return ans;
        }
    };
    

    第四题 5775. 准时抵达会议现场的最小跳过休息次数

    题目链接:5775. 准时抵达会议现场的最小跳过休息次数

    • dp[i][j]表示经过了前i段道路(i1开始)、跳过j次的最短用时。考虑到精度问题,这里数组是二维的double数组
    • 考虑状态转移,对于dp[i][j]
      • 如果跳过当前道路dist[i - 1],则有:dp[i][j] = dp[i - 1][j - 1] + dist[i - 1] / speed
      • 如果不跳过当前道路dist[i - 1],则有:dp[i][j] = ceil(dp[i - 1][j] + dist[i - 1] / speed)
    • 边界情况:
      • j = 0时,表示我们不跳过任何道路,则dp[i][j]无法由任何“跳过道路”的状态转移得到
      • j = i时,表示我们跳过了所有道路,则dp[i][j]无法由任何“不跳过道路”的状态转移得到
      • 跳过次数j应该小于道路数i
    • 最终答案:
      • 对于所有的小于等于hoursBeforedp[n][i](该状态表示通过了所有道路,跳过i次的最短用时),我们找到最小的那个i,作为结果返回即可
      • 如果在0 ~ n的范围内没有找到满足条件的i,那么返回-1
    • 其他细节:
      • 考虑到精度问题,向上取整操作ceil()有可能会得到错误答案,常见的做法是减去一个误差值eps之后再向上取整
    • 参考资料:官方题解
    class Solution {
    private:
        const double INF = 1e10;
        const double eps = 1e-8;
        int n;
        vector<vector<double>> dp;
        
    public:
        int minSkips(vector<int>& dist, int speed, int hoursBefore) {
            n = dist.size();
            dp.resize(n + 1, vector<double>(n + 1, INF));
            dp[0][0] = 0;
            for(int i = 1; i <= n; ++i) {
                for(int j = 0; j <= i; ++j) {
                    dp[i][j] = min(dp[i][j], ceil(dp[i - 1][j] + (double)dist[i - 1] / speed - eps));
                    if(0 < j) {
                        dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + (double)dist[i - 1] / speed);
                    }
                }
            }
            for(int i = 0; i <= n; ++i) {
                if(dp[n][i] <= hoursBefore) {
                    return i;
                }
            }
            return -1;
        }
    };
    
  • 相关阅读:
    OSI参考模型(转)
    H3C交换机配置常用命令(转)
    H3C交换机配置学习随笔
    [Swust OJ 247]--皇帝的新衣(组合数+Lucas定理)
    [Swust OJ 1084]--Mzx0821月赛系列之情书(双线程dp)
    [Swust OJ 404]--最小代价树(动态规划)
    [Swust OJ 610]--吉祥数
    [Swust OJ 137]--波浪数(hash+波浪数构造)
    [Swust OJ 566]--开N方数(牛顿切线法解高次方程)
    [Swust OJ 1125]--又见GCD(数论,素数表存贮因子)
  • 原文地址:https://www.cnblogs.com/linrj/p/14830735.html
Copyright © 2011-2022 走看看