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

    Leetcode 第243场周赛

    前两题简单。

    第三题一个模拟,容易边界处理不好。

    第四题dp,卡精度。

    第一题

    https://leetcode-cn.com/problems/check-if-word-equals-summation-of-two-words/

    直接算就行。

    class Solution {
    public:
        bool isSumEqual(string firstWord, string secondWord, string targetWord) {
          int x1 = 0;
          for(auto c:firstWord){
            x1 = x1 * 10 + (c - 'a');
          }
          
          int x2 = 0;
          for(auto c:secondWord){
            x2 = x2 * 10 + (c - 'a');
          }
          
          int x3 = 0;
          for(auto c:targetWord){
            x3 = x3 * 10 + (c - 'a');
          }
          
          return x1 + x2 == x3;
        }
    };
    

    第二题

    https://leetcode-cn.com/problems/maximum-value-after-insertion/

    1. 正负要分情况讨论。
    2. 从左向右插入,找第一个比自己小,或者比自己大的位置。
    3. string insert的api总是记不住:
    // 这两个用的比较多
    区别就是单字节和字符串,前者可以重重复count次字符,后者就是直接插入一个字符串。
    
    // insert(size_type index, size_type count, char ch)
    s.insert(0, 1, 'E');
    assert("Exmplr" == s);
    
    // insert(size_type index, const char* s)
    s.insert(2, "e");
    assert("Exemplr" == s);
    

    代码:

    class Solution {
    public:
        string maxValue(string n, int x) {
          int nn = n.size();
          int tar_index = 0;
          tar_index = nn;
          if(n[0] == '-'){
            for(int i = 1 ; i < nn ; ++i){
              if(n[i] - '0' <= x) continue;
              else {
                tar_index = i;
                break;
              }
            }
          } else {
            for(int i = 0 ; i < nn ; ++i){
              if(n[i] - '0' >= x) continue;
              else {
                tar_index = i;
                break;
              }
            }
          }
          if(tar_index == nn) n.push_back(x + '0');
          else n.insert(tar_index, 1, x + '0');
          return n;
        }
    };
    

    第三题

    https://leetcode-cn.com/problems/process-tasks-using-servers/

    大概思路是维护两个堆,第一个是可以用的服务器(idle),第二个是正在被使用的服务器(busy)。两边来回对调。

    这个题没必要自定义排序,C++pair是自带排序的,先比较第一个,再比较第二个。所以小顶堆用greater<>或者大顶堆用less<>就可以了。

    数据存的分别是:idle存权值w和下标idx,busy存等待时间t和idx。两边交换依靠idx唯一确定服务器。

    然后是注意考虑一个堆为空的情况。

    最后是时间的更新,不用循环每次+1,只要分情况就可以:

    • idle为空,这时候time要一直等到最快一个完成才行,所以直接等过去就就好。
    • busy为空,这时候直接等于当前下标最小的任务即可。
    • 普通情况,应该是等于前面二者之间最小的那个。因为事件是按顺序发生的,如果某个该发生的事件时间被跳过去,后面的事件可能就都错乱了。所以应该先处理时间最小的那个。
    class Solution {
    public:
        vector<int> assignTasks(vector<int>& servers, vector<int>& tasks) {
          int n = servers.size();
          int m = tasks.size();
          priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> idle_server_pool;
          priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> busy_server_pool;
          
          for(int i = 0 ; i < n ; ++i){
            idle_server_pool.push(make_pair(servers[i], i));
          }
    
          int cur_time = 0;
          vector<int> ret(m, 0);
          int i = 0;
          while(i < m){
            if(idle_server_pool.empty()) cur_time = busy_server_pool.top().first;
            else if (busy_server_pool.empty()) cur_time = i;
            else cur_time = min(i, busy_server_pool.top().first);
    
            while(!busy_server_pool.empty() && busy_server_pool.top().first <= cur_time){
              idle_server_pool.push(make_pair(servers[busy_server_pool.top().second], busy_server_pool.top().second));
              busy_server_pool.pop();
            }
    
            while(i < m && cur_time >= i && !idle_server_pool.empty()){
              ret[i] = idle_server_pool.top().second;
              busy_server_pool.push(make_pair(cur_time + tasks[i], idle_server_pool.top().second));
              idle_server_pool.pop();
              ++i;
            }
          }
          return ret;
    
        }
    };
    

    第四题

    https://leetcode-cn.com/problems/minimum-skips-to-arrive-at-meeting-on-time/

    这个题是一个中等难度的dp

    题解讲的很好,理解起来也不难。

    其中有三个点比较难

    1. 下面代码的注释,是两种特殊情况,即跳跃次数为0和跳跃次数为1的情况。转移时必须注意。
    2. 初始化的问题,全部为INT_MAX。但是dp[0][0]应该是0
    3. 卡精度的问题,eps的使用方法

    代码

    class Solution {
    public:
        const double eps = 1e-9;
        int minSkips(vector<int>& dist, int speed, int hoursBefore) {
          int n = dist.size();
          vector<vector<double>> dp(n + 1, vector<double>(n + 1,INT_MAX));
          dp[0][0] = 0;
          for(int i = 1 ; i <= n ; ++i){
            for(int j = 0 ; j <= i ; ++j){
              if(j != 0){
                // 当跳跃次数为0时,不能从「上次跳跃」转移过来
                // 此次转移为:上次跳跃
                dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + dist[i - 1]/(double)speed);
              }
              if(j != i){
                // 当跳跃次数与路的数量一致时,每一段路都跳跃。此时不能从「上次不跳跃」转移过来
                // 此次转移为:上次不跳跃
                dp[i][j] = min(dp[i][j], ceil(dp[i - 1][j] + dist[i - 1]/(double)speed - eps));
              }
            }
          }
    
          for(int j = 0 ; j <= n ; ++j){
            if(dp[n][j] <= hoursBefore) return j;
          }
          return -1;
        }
    };
    
  • 相关阅读:
    python 登陆接口
    FTP 的搭建过程和遇到的问题
    ELK 的好文章连接
    logstash 配置文件实例
    使用 screen 管理你的远程会话
    Conda常用命令整理
    python 增加矩阵行列和维数
    26个你不知道的Python技巧
    python单下划线、双下划线、头尾双下划线说明:
    python 类方法的互相调用及self的含义
  • 原文地址:https://www.cnblogs.com/molinchn/p/14829701.html
Copyright © 2011-2022 走看看