【2022/04/17-第289场单周赛】 复盘

Q1.计算字符串的数字和

Q1链接
题意:字符串长度大于k时,每k个字符都各自转换为对应个位数然后相加,结果转化成对应字符串,然后所有结果字符串加到一起代替原字符串。直到字符串长度小于等于k为止。

class Solution {
public:
    string digitSum(string s, int k) {
        while(s.size() > k){
            int cnt = 0, x = 0;
            string temp, ss;
            for(auto i : s){
                x += i - '0';
                ++cnt;
                if(cnt == k){
                    cnt = 0;
                    ss += to_string(x);
                    x = 0;
                }
            }
            if(cnt) ss += to_string(x);
            s = ss;
        }
        return s;
    }
};

水题。

Q2.完成所有任务需要的最少轮数

Q2链接
题意:某个任务的数量x为1就直接返回-1,否则结果加上(x + 2) / 3。

class Solution {
public:
    int minimumRounds(vector<int>& tasks) {
        unordered_map<int, int> mp;
        for(auto i : tasks) ++mp[i];
        int ret = 0;
        for(auto i : mp){
            if(i.second == 1) return -1;
            else ret += ((i.second + 2) / 3);
        }
        return ret;
    }
};

水题。

Q3.转角路径的乘积中最多能有几个尾随零

Q3链接
题意:对于每条只有一个转角的路径,把路径上所有数总共的2的因子个数和总共的5的因子个数求出来,然后返回两者较小值。
用前缀和维护每个位置向上和向左路径中2和5的因子个数。

class Solution {
public:
    int maxTrailingZeros(vector<vector<int>>& g) {
        int m = g.size(), n = g[0].size();
        vector<vector<int>> m2(m, vector<int> (n, 0)), m5(m, vector<int> (n, 0));
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                int p2 = 0, p5 = 0;
                while(g[i][j] % 2 == 0){
                    g[i][j] /= 2;
                    ++p2;
                }
                while(g[i][j] % 5 == 0){
                    g[i][j] /= 5;
                    ++p5;
                }
                m2[i][j] = p2;
                m5[i][j] = p5;
            }
        }
        vector<vector<int>> ps2h(m + 1, vector<int> (n + 1, 0)), ps5h(m + 1, vector<int> (n + 1, 0)), ps2s(m + 1, vector<int> (n + 1, 0)), ps5s(m + 1, vector<int> (n + 1, 0));
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                ps2h[i + 1][j + 1] = ps2h[i + 1][j] + m2[i][j];
                ps5h[i + 1][j + 1] = ps5h[i + 1][j] + m5[i][j];
                ps2s[i + 1][j + 1] = ps2s[i][j + 1] + m2[i][j];
                ps5s[i + 1][j + 1] = ps5s[i][j + 1] + m5[i][j];
            }
        }
        int ret = 0;
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                int zs2 = ps2h[i + 1][j + 1] + ps2s[i + 1][j + 1] - m2[i][j], zs5 =  ps5h[i + 1][j + 1] + ps5s[i + 1][j + 1] - m5[i][j];
                ret = max(ret, min(zs2, zs5));
                int zx2 = ps2h[i + 1][j + 1] + ps2s[m][j + 1] - ps2s[i + 1][j + 1], zx5 = ps5h[i + 1][j + 1] + ps5s[m][j + 1] - ps5s[i + 1][j + 1];
                ret = max(ret, min(zx2, zx5));
                int yx2 = ps2h[i + 1][n] - ps2h[i + 1][j + 1] + ps2s[m][j + 1] - ps2s[i + 1][j + 1] + m2[i][j], yx5 = ps5h[i + 1][n] - ps5h[i + 1][j + 1] + ps5s[m][j + 1] - ps5s[i + 1][j + 1] + m5[i][j];
                ret = max(ret, min(yx2, yx5));
                int ys2 = ps2h[i + 1][n] - ps2h[i + 1][j + 1] + ps2s[i + 1][j + 1], ys5 = ps5h[i + 1][n] - ps5h[i + 1][j + 1] + ps5s[i + 1][j + 1];
                ret = max(ret, min(ys2, ys5));
            }
        }
        return ret;
    }
};

前缀和下标处理还是挺麻烦的。
前缀和计算有优化空间。

Q4.相邻字符不同的最长路径

Q4链接
题意:在一张图中,找到相邻字母不同的最长路径。
可以利用树的直径求法。

class Solution {
public:
    
    vector<int> adj[100010];
    int visit1[100010], temp, visit2[100010], f, maxd = 0;
    
    void DFS1(int s, int depth){
        if(depth > maxd){
            maxd = depth;
            f = s;
        }
        for(auto i : adj[s]){
            if(!visit1[i]){
                visit1[i] = 1;
                DFS1(i, depth + 1);
            }
        }
    }
    
    void DFS2(int s, int depth){
        if(depth > maxd){
            maxd = depth;
        }
        for(auto i : adj[s]){
            if(!visit2[i]){
                visit2[i] = 1;
                DFS2(i, depth + 1);
            }
        }
    }
    
    
    int longestPath(vector<int>& parent, string s) {
        int n = parent.size(), ret = 1;
        memset(visit1, 0, 100010);
        memset(visit2, 0, 100010);
        for(int i = 0; i < n; ++i) adj[i].clear();
        
        for(int u = 1; u < n; ++u){
            int v = parent[u];
            if(s[u] != s[v]){
                adj[u].push_back(v);
                adj[v].push_back(u);
            }
        }
        
        for(int i = 0; i < n; ++i){
            if(!visit1[i]){
                visit1[i] = 1;
                maxd = 0;
                DFS1(i, 1);
                visit2[f] = 1;
                maxd = 0;
                DFS2(f, 1);
                ret = max(ret, maxd);
            }
        }
        return ret;
    }
};
posted on 2022-04-30 00:35  damnglamour  阅读(29)  评论(0)    收藏  举报