【2022/07/17-第302场单周赛】

总结

手速场。

Q1.数组能形成多少数对

根据数据范围,用哈希表一对一对找即可。

class Solution {
public:
    vector<int> numberOfPairs(vector<int>& a) {
        int h[110]; memset(h, 0, sizeof(h));
        for(auto i : a) ++h[i];
        vector<int> ret{0, 0};
        for(int i = 0; i < 110; ++i){
            ret[0] += h[i] / 2;
            ret[1] += h[i] & 1;
        }
        return ret;
    }
};

Q2.数位和相等数对的最大和

以数位和为键,用优先队列存储每个数位和下的所有数,然后找到最大值。

class Solution {
public:
    int maximumSum(vector<int>& a) {
        map<int, priority_queue<int, vector<int>, less<int> > > mp;
        for(auto i : a){
            int t = 0, x = i;
            while(x){
                t += x % 10;
                x /= 10;
            }
            mp[t].push(i);
        }
        int ret = -1;
        for(auto &i : mp){
            if(i.second.size() >= 2){
                int x = i.second.top(); i.second.pop();
                x += i.second.top();
                ret = max(ret, x);
            }
        }
        return ret;
    }
};

Q3.裁剪数字后查询第 K 小的数字

对于每个查询都排序,然后得到结果。

class Solution {
public:
    vector<int> smallestTrimmedNumbers(vector<string>& a, vector<vector<int>>& q) {
        int n = a.size(), m = a[0].size();
        map<string, vector<int>> mp;
        for(int i = 0; i < n; ++i){
            mp[a[i]].push_back(i);
        }
        vector<int> ret;
        for(auto &i : q){
            int k = i[0], len = i[1];
            sort(a.begin(), a.end(), [&](const string &s, const string &t){
                for(int j = m - len; j < s.size(); ++j){
                    if(s[j] < t[j]) return true;
                    if(s[j] > t[j]) return false;
                }
                return mp[s] < mp[t];
            });
            string ts = a[k - 1];
            int pre = 0;
            for(int j = k - 2; j >= 0; --j){
                if(a[j] == ts) ++pre;
                else break;
            }
            ret.push_back(mp[ts][pre]);
        }
        return ret;
    }
};

先排好序再查询

class Solution {
public:
    vector<int> smallestTrimmedNumbers(vector<string>& a, vector<vector<int>>& q) {
        int n = a[0].size();
        vector<int> v, ret;
        for(int i = 0; i < a.size(); ++i) v.push_back(i);
        vector<string> mp = a;
        unordered_set<int> st;
        for(auto &i : q) st.insert(i[1]);
        for(int i = 0; i < a.size(); ++i) mp[i] = a[i];
        vector<int> b[n + 1];
        for(auto & i : st){
            sort(v.begin(), v.end(), [&](int x, int y){
                for(int j = n - i; j < n; ++j){
                    if(mp[x][j] < mp[y][j]) return true;
                    else if(mp[x][j] > mp[y][j]) return false;
                }
                return x < y;
            });
            b[i] = v;
        }
        for(auto &i : q){
            ret.push_back(b[i[1]][i[0] - 1]);
        }
        return ret;
    }
};

Q4.使数组可以被整除的最少删除次数

找到第二个数组最大公因数,对第一个数组排序,然后逐个判断即可。

class Solution {
public:
     
    int minOperations(vector<int>& a, vector<int>& d) {
        int x = d[0], ret = 0;
        function<int(int, int)> gcd = [&](int a, int b){
            if(b > a) swap(a, b);
            return a % b == 0 ? b : gcd(b, a % b);
        };
        for(int i = 1; i < d.size(); ++i) x = gcd(x, d[i]);
        sort(a.begin(), a.end());
        for(auto i : a){
            if(x % i == 0) return ret;
            else ++ret;
        }
        return -1;
    }
};
posted on 2022-07-17 12:13  damnglamour  阅读(23)  评论(0)    收藏  举报