第 314 场周赛 题解

78 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情

6200. 处理用时最长的那个任务的员工

共有 n 位员工,每位员工都有一个从 0 到 n - 1 的唯一 id 。

给你一个二维整数数组 logs ,其中 logs[i] = [idi, leaveTimei] :

  • idi 是处理第 i 个任务的员工的 id ,且
  • leaveTimei 是员工完成第 i 个任务的时刻。所有 leaveTimei 的值都是 唯一 的。

注意,第 i 个任务在第 (i - 1) 个任务结束后立即开始,且第 0 个任务从时刻 0 开始。

返回处理用时最长的那个任务的员工的 id 。如果存在两个或多个员工同时满足,则返回几人中 最小 的 id 。

思路

记录一下当前和前面日志的时间差,加入到map当中去
搞完之后,取出最后一项

代码

class Solution {
public:
    int hardestWorker(int n, vector<vector<int>>& logs) {
        int pre = 0;
        map<int, int> mp;
        for (int i = 0; i < logs.size(); i ++) {
            int k = logs[i][1] - pre;
            if (mp.count(k)) mp[k] = min(mp[k], logs[i][0]);
            else mp[k] = logs[i][0];
            pre = logs[i][1];
        }
        auto t = mp.end();
        t --;
        return t->second;
    }
};

6201. 找出前缀异或的原始数组

给你一个长度为 n 的 整数 数组 pref 。找出并返回满足下述条件且长度为 n 的数组 **arr :

  • pref[i] = arr[0] ^ arr[1] ^ ... ^ arr[i].

注意 ^ 表示 按位异或(bitwise-xor)运算。

可以证明答案是 唯一 的。

思路

异或的运算是可逆的

所以,我们直接异或回去就ok了

因为 ab=c=>ac=ba \bigoplus b = c => a \bigoplus c = b

代码


class Solution {
public:
    vector<int> findArray(vector<int>& pref) {
        vector<int> ans;
        int now = 0;
        for (auto v : pref) {
            ans.push_back(now ^ v);
            now ^= ans.back();
        }
        return ans;
    }
};

6202. 使用机器人打印字典序最小的字符串

给你一个字符串 s 和一个机器人,机器人当前有一个空字符串 t 。执行以下操作之一,直到 s 和 t 都变成空字符串:

  • 删除字符串 s 的 第一个 字符,并将该字符给机器人。机器人把这个字符添加到 t 的尾部。
  • 删除字符串 t 的 最后一个 字符,并将该字符给机器人。机器人将该字符写到纸上。

请你返回纸上能写出的字典序最小的字符串。

思路

尽可能小的字典序

我们应该尽可能的把所有 a,先输出,其次是b,其次是c

这个可以最小,但是我们的t数组压入之后,顺序就确定了

所以,我们要关心s数组当前存在的最小值

我们拿到s数组当前存在的最小值之后,在t数组中末尾的和s数组当前当前元素凡是小于等于它自己的,都可以压入栈。

代码

class Solution {
public:
    string robotWithString(string s) {
        map<char, int> mp;
        string ans;
        string sta;
        for (auto v : s) mp[v] ++;
        mp['z'] ++;
        for (auto v : s) {
            auto t = mp.begin();
            while (sta.size() && sta.back() <= t->first) 
                ans.push_back(sta.back()), sta.pop_back();
            if (v == t->first) {
                ans.push_back(v);
            } else {
                sta.push_back(v);
            }
            mp[v] --;
            if (mp[v] == 0) {
                mp.erase(v);
            }
        }
        while (sta.size()) ans.push_back(sta.back()), sta.pop_back();
        return ans;
    }
};

6203. 矩阵中和能被 K 整除的路径

给你一个下标从 0 开始的 m x n 整数矩阵 grid 和一个整数 k 。你从起点 (0, 0) 出发,每一步只能往  或者往  ,你想要到达终点 (m - 1, n - 1) 。

请你返回路径和能被 k 整除的路径数目,由于答案可能很大,返回答案对 109 + 7 取余 的结果。

思路

首先,我们按照正常的dp思路来记录方案是如何做的呢?

有如下dp方程

dp[0][j]=1dp[i][0]=1dp[i][j]=dp[i1][j]+dp[i][j1]dp[0][j] = 1 \\ dp[i][0] = 1 \\ dp[i][j] = dp[i-1][j] + dp[i][j-1]

我们来分析一下加了 能被k整除的路径数目这一限制下,我们如何做

那么,设上一步的值为 xx,现在值变成了 x+grid[i][j]x + grid[i][j],那么,我们可以把这些数分为 k类 即 0,1,2,...,k10, 1, 2, ..., k-1,分别表示值对k取模的余数

于是,最后一项就是 dp[n1][m1][0]dp[n-1][m-1][0]

我们枚举的时候,只需要再去枚举一下余数,我们就可以转移得到当前的方程了

for (int w = 0; w < k; w ++) {
    int ne = (w + grid[i][j]) % k;
    dp[i][j][ne] = (dp[i][j][ne] + dp[i-1][j][w]) % MOD;
    dp[i][j][ne] = (dp[i][j][ne] + dp[i][j-1][w]) % MOD;
}

代码

class Solution {
public:
    static int const MOD = 1e9 + 7;
    int numberOfPaths(vector<vector<int>>& grid, int k) {
        int n = grid.size();
        int m = grid.back().size();
        vector<vector<vector<long long>>> dp(n, vector<vector<long long>>(m, vector<long long>(k, 0)));
        dp[0][0][grid[0][0] % k] = 1;
        for (int i = 1, pre = grid[0][0]; i < n; i ++) {
            pre += grid[i][0];
            dp[i][0][pre % k] = 1;
        }
        for (int i = 1, pre = grid[0][0]; i < m; i ++) {
            pre += grid[0][i];
            dp[0][i][pre % k] = 1;
        }
        for (int i = 1; i < n; i ++)
        for (int j = 1; j < m; j ++) {
            for (int w = 0; w < k; w ++) {
                int ne = (w + grid[i][j]) % k;
                dp[i][j][ne] = (dp[i][j][ne] + dp[i-1][j][w]) % MOD;
                dp[i][j][ne] = (dp[i][j][ne] + dp[i][j-1][w]) % MOD;
            }
        }
        
        return dp[n-1][m-1][0];
    }
};