返回顶部

LeetCode第 288 场周赛题解

6037. 按奇偶性交换后的最大数字

题目描述:给你一个正整数 num 。你可以交换 num奇偶性 相同的任意两位数字(即,都是奇数或者偶数)。返回交换 任意 次之后 num最大 可能值

思路:将奇偶分开排序后贪心即可。

时间复杂度:\(O(nlogn)\)\(n\)为数字num的位数

参考代码:

class Solution {
public:
    int largestInteger(int num) {
        vector<int>cnt(10 , 0);
        string s = to_string(num);
        vector<int>even , odd;
        for(auto&& c : s){
            int val = c - '0';
            if(val & 1) even.push_back(val);
            else odd.push_back(val);
        }
        sort(even.begin() , even.end());
        sort(odd.begin() , odd.end());
        int p = (int)even.size() - 1 , q = (int)odd.size() - 1;
        int res = 0;
        for(int i = 0 ; i < s.size() ; ++i){
            int val = s[i] - '0';
            if(val & 1) res = res * 10 + even[p--];
            else res = res * 10 + odd[q--];
        }
        return res;
    }
};

6038. 向表达式添加括号后的最小结果

题目描述:给你一个加法算式,让你在加号两边添加括号,问加括号之后整个算式取得最小值时的表达式是什么。

思路:考虑到表达式长度比较小,所以找到加号的位置之后暴力枚举括号的位置即可。

时间复杂度:\(O(n^3)\)\(n\)为表达式的长度。

参考代码:

class Solution {
public:
    string minimizeResult(string e) {
        
        int idx = 0 , n = e.size();
        while(e[idx] != '+') ++idx;
        string res;
        int mx = INT_MAX;
        for(int i = 0 ; i <= idx - 1; ++i){
            for(int j = idx + 1 ; j < n ; ++j){
                int cur = 0, cnt = 0;
                for(int k = 0 ; k < i ; ++k) cnt = cnt * 10 + e[k] - '0';
                if(cnt == 0) cnt = 1;
                cur = cnt;
                int lr = 0 , rs = 0;
                for(int k = i ; k < idx ; ++k) lr = lr * 10 + e[k] - '0';
                for(int k = idx + 1 ; k <= j ; ++ k) rs = rs * 10 + e[k] - '0';
                cur = cur * (lr + rs);
                cnt = 0;
                for(int k = j + 1 ; k < n ; ++k) cnt = cnt * 10 + e[k] - '0';
                if(cnt == 0) cnt = 1;
                cur *= cnt;
                if(cur < mx){
                    mx = cur;
                    res.clear();
                    for(int k = 0 ; k < n ; ++k){
                        if(k == i) res += '(';
                        res += e[k];
                        if(k == j) res += ')';
                    }
                }
            }
        }
        return res;
    }
};

6039. K 次增加后的最大乘积

题目描述:给你一个数组和一个整数\(k\),你可以从数组中选出一个数,然后对它执行+1操作,总共的操作次数不超过k,问最后数组所有元素的乘积的最大值是多少?答案对1e9+7取模。

思路:比较明显的贪心,每次选取最小的数字对其执行+1操作即可。

时间复杂度:\(O(nlogn)\)

参考代码:

class Solution {
public:
    int maximumProduct(vector<int>& nums, int k) {
        priority_queue<int , vector<int> , greater<int>>heap;
        for(auto&& num : nums) heap.push(num);
        while(k--){
            int dx = heap.top();heap.pop();
            heap.push(dx + 1);
        }
        int res = 1;
        const int mod = 1e9 + 7;
        while(!heap.empty()){
            int dx  = heap.top();heap.pop();
            res = 1ll * res * dx % mod;
        }
        return res;
    }
};

6040. 花园的最大总美丽值

题目描述:有\(n\)个花园,若一个花园种的花的数量不少于target,则可获得full点价值,若所有种的花的数量少于target的花园中,种的花的最小数目是x,那么可以获得\(x \times partial\)点价值。现在这\(n\)个花园中已经种了一些花,你总共额外可以种newFlowers朵,问你最终获得的价值的最大值是多少。

思路:我们先对花园按照种的花的数量进行逆序排序,然后顺序枚举,若枚举到\(i\),表示前\(i\)个花园中种的花的数量都至少为target,对于剩下的花园,考虑二分其最小值,然后使用树状数组去求满足最小值需要的花的数量进行检验即可。

时间复杂度:\(O(nlog^2n)\)

参考代码:

class Solution {
public:
    long long maximumBeauty(vector<int>& flowers, long long allf, int target, int full, int partial) {
        long long res = 0, sum = 0;
        multiset<int> s;
        const int N = 1e5 + 5;
        vector<long long> tr(100005 , 0);
        vector<long long>tridx(N , 0);
        for(auto&& flower : flowers){
            if(flower >= target) sum += full;
            else s.insert(flower);
        }
        auto lowbit = [](int x){return x &-x;};
        auto add = [&](vector<long long>& tr , int idx , int val){
            while(idx < N){
                tr[idx] += val;
                idx += lowbit(idx);
            }
            return ;
        };
        auto getsum = [&](vector<long long>& tr , int idx)->long long{
            long long ans = 0;
            while(idx != 0){
                ans += tr[idx];
                idx -= lowbit(idx);
            }
            return ans;
        };
        vector<int>nums;
        for(auto&& val : s){
            add(tr , val , val);
            add(tridx , val , 1);
            nums.push_back(val);
        }
        nums.push_back(target);
        reverse(nums.begin() , nums.end());
        int n = nums.size();
        res = sum;
        for(int i = 0 ; i < n ; ++i){
            int dx = target - nums[i];
            if(i != 0)add(tr , nums[i] , -nums[i]);
            if(i != 0)add(tridx , nums[i] , -1);
            allf -= dx;
            if(allf < 0) break;
            if(i != 0) sum += full;
            if(i == n - 1) break;
            int lr = 1 , rs = target - 1, pos = 0;
            while(lr <= rs){
                int mid = lr + rs >> 1;
                int cnt = getsum(tridx , mid);
                long long tmpsum = getsum(tr , mid);
                long long need = 1ll * cnt * mid - tmpsum;
                if(need <= allf) lr = mid + 1 , pos = mid;
                else rs = mid - 1;
            }
            res = max(res , sum + 1ll * pos * partial);
        }
        res = max(res , sum);
        return res;
    }
};
posted @ 2022-04-10 16:54  cherish-lgb  阅读(35)  评论(0编辑  收藏  举报