【2022-06-12-第297场单周赛】

总结

迟到了,可惜没进国服前100。

Q1.计算应缴税款总额

模拟。

class Solution {
public:
    double calculateTax(vector<vector<int>>& br, int ic) {
        double ret = 0;
        if(ic <= br[0][0]) return (double)ic * br[0][1] / 100;
        ret += (double)br[0][0] * br[0][1] / 100;
        for(int i = 1; i < br.size(); ++i){
            if(ic <= br[i][0]){
                ret += (double)(ic - br[i - 1][0]) * br[i][1] / 100;
                return ret;
            }
            ret += (double)(br[i][0] - br[i - 1][0]) * br[i][1] / 100;
        }
        return ret;
    }
};

Q2.网格中的最小路径代价

dp模板题。

class Solution {
public:
    int minPathCost(vector<vector<int>>& g, vector<vector<int>>& c) {
        int m = g.size(), n = g[0].size();
        int dp[m][n];
        for(int i = 0; i < n; ++i) dp[0][i] = g[0][i];
        for(int i = 1; i < m; ++i){
            for(int j = 0; j < n; ++j){
                dp[i][j] = dp[i - 1][0] + c[g[i - 1][0]][j] + g[i][j];
                for(int k = 1; k < n; ++k){
                    dp[i][j] = min(dp[i][j], dp[i - 1][k] + c[g[i - 1][k]][j] + g[i][j]);
                }
            }
        }
        int ret = INT_MAX;
        for(int i = 0; i < n; ++i){
            ret = min(ret, dp[m - 1][i]);
        }
        return ret;
    }
};

Q3.公平分发饼干

回溯剪枝。

class Solution {
public:
    int distributeCookies(vector<int>& c, int k) {
        int n = c.size();
        if(k == n) return *max_element(c.begin(), c.end());
        vector<int> temp(k, 0);
        int ret = INT_MAX;
        int vis[n]; memset(vis, 0, sizeof(vis));
        function<void(int)> dfs = [&](int idx){
            if(*max_element(temp.begin(), temp.end()) > ret) return ;
            if(idx == n){
                ret = min(ret, *max_element(temp.begin(), temp.end()));
                return ;
            }
            for(int i = 0; i < k; ++i){
                temp[i] += c[idx];
                dfs(idx + 1);
                temp[i] -= c[idx];
            }
        };
        dfs(0);
        return ret;
    }
};

Q4.公司命名

对于"abb",如果当其首字母替换成b时,"bbb"不存在于id中,那我们可以考虑所有首字母为b的字符串作为组合对象,只需要这个b开头的字符串首字母替换成a时也不存在于id中,就牵手成功。
首先我们根据首字母划分,把"去掉首字母的字符串"放到对应哈希表st[i]中,便于判断替换后字符串是否存在于id中。
用can[n][26]数组记录每个字符串是否可以将首字母替换成某个字母,用a[26][26]数组记录首字母可以从字母1替换成字母2的个数。
通过哈希表计算字符串si是否可以将首字母char1替换成某个字母char2,如果可以,则can[i][char2 - 'a'] = 1,代表si可以将char1替换成char2,同时a[(char1 - 'a') * 26 + (char2 - 'a')] += 1,表示首字母可以从char1替换成char2的字符串数目+1。
最后我们遍历id,对每个首字母为char1的字符串si,若can[i][char2 - 'a'] == 1,则结果加上首字母可以从char2替换成char1的字符串数目,即a[(char2 - 'a') * 26 + (char1 - 'a')];

class Solution {
public:
    long long distinctNames(vector<string>& id) {
        int n = id.size(), a[26 * 26], can[n][26];
        memset(a, 0, sizeof(a)), memset(can, 0, sizeof(can));
        unordered_set<string> st[26]; // set会超时
        
        for(int i = 0; i < n; ++i) st[id[i][0] - 'a'].insert(id[i].substr(1, id[i].size() - 1));
        
        for(int j = 0; j < n; ++j){
            string t = id[j].substr(1, id[j].size() - 1);
            for(int i = 0; i < 26; ++i){
                if(id[j][0] - 'a' != i && st[i].find(t) == st[i].end()){
                    ++a[(id[j][0] -'a') * 26 + i];
                    can[j][i] = 1;
                }
            }
        }
        long long ret = 0;
        for(int i = 0; i < n; ++i){
            for(int j = 0; j < 26; ++j){
                if(can[i][j]) ret += a[j * 26 + id[i][0] - 'a'];
            }
        }
        return ret;
    }
};
posted on 2022-06-12 20:53  damnglamour  阅读(31)  评论(0)    收藏  举报