首页 > 其他分享 >357周赛

357周赛

时间:2023-08-06 16:44:08浏览次数:30  
标签:周赛 dist int st 357 vector && return

故障键盘

image

水题。

class Solution {
public:
    string finalString(string s) {
        string res;
        for (char c : s) {
            if (c == 'i') {
                reverse(res.begin(), res.end());
            } else {
                res += c;
            }
        }
        return res;
    }
};

判断能否拆分数组

image

要把长度为n的数组拆成n个子数组,就说明最后的所有子数组长度都为1。这个肯定是可以做到的,那么问题就是中间拆分过程中产生的长度不为1的子数组,能否满足其值≥m?如果能找到一个长度为2的子数组,其值≥m,那么就可以保证中间产生的所有子数组都≥m。
假设那个子数组在左边,我们第一次一分为二,可以右边只留一个,那么右边长度为1,必然合法,左边因为子数组存在,也不可能小于m,也合法。就这样温水煮青蛙,一次拿一个出来,所有这种方案是必然合法的。

所有检测是否存在长度为2的子数组值≥m即可。

class Solution {
public:    
    bool canSplitArray(vector<int>& nums, int m) {
        if (nums.size() <= 2) {
            return true;
        }
        for (int i = 0; i < nums.size() - 1; ++i) {
            if (nums[i] + nums[i + 1] >= m) {
                return true;
            }
        }
        return false;
    }
};

找出最安全路径

image

先用多源BFS,预处理出每一个点的安全系数。
然后二分答案,用BFS检测,要求节点不小于这个安全系数的情况下,是否存在一条从起点到终点的路径。

class Solution {
public:
    constexpr static int dx[4] = {0, 1, 0, -1};
    constexpr static int dy[4] = {-1, 0, 1, 0};
    int n, m;
    vector<vector<int>> st;
    vector<vector<int>> dist;

    bool check(int mid)
    {
        if (dist[0][0] < mid) return false;

        using PII = pair<int, int>;
        queue<PII> q;
        q.push({0, 0});

        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                st[i][j] = false;
        st[0][0] = true;

        while (!q.empty())
        {
            auto t = q.front(); q.pop();
            if (t.first == n - 1 && t.second == m - 1) return true;

            for (int i = 0; i < 4; ++i)
            {
                int x = t.first + dx[i], y = t.second + dy[i];
                if (x >= 0 && x < n && y >= 0 && y < m && !st[x][y] && dist[x][y] >= mid)
                    q.push({x, y}), st[x][y] = true;
            }
        }
        return false;
    }
    
    int maximumSafenessFactor(vector<vector<int>>& grid) 
    {
        n = grid.size(), m = grid[0].size();
        if (grid[0][0] == 1 || grid[n - 1][m - 1] == 1) return 0;
        
        st = vector<vector<int>>(n, vector<int>(m));
        dist = vector<vector<int>>(n, vector<int>(m, 0x3f3f3f3f)); // 预处理所有格子到小偷的最短曼哈顿距离
        using PII = pair<int, int>;
        queue<PII> q;
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                if (grid[i][j] == 1)
                    q.push({i, j}), dist[i][j] = 0;
        while (!q.empty())
        {
            auto [x, y] = q.front(); q.pop();
            for (int i = 0; i < 4; ++i)
            {
                int sx = x + dx[i], sy = y + dy[i];
                if (sx >= 0 && sx < n && sy >= 0 && sy < m && dist[sx][sy] == 0x3f3f3f3f)
                    dist[sx][sy] = dist[x][y] + 1, q.push({sx, sy});
            }
        }

        int l = 0, r = min(dist[0][0], dist[n - 1][m - 1]);
        while (l < r)
        {
            int mid = l + r + 1 >> 1;
            if (check(mid))
                l = mid;
            else
                r = mid - 1;
            printf("---%d\n", r);
        }
        puts("-----");
        return r;
    }       
};

子序列的最大优雅度

image

优雅度由两个维度,一个是利润,一个是种类数。
可以使用反悔贪心来做,首先按照利润从大到小排序,选取前k个,这个就是可能的最大利润和了。
之后对剩下的每一个项,有以下几种情况:

  1. 这个项目的类别和前k个项目的类型重复,选它必然不会使得答案变好。
  2. 这个项目的类别和前k个项目的类型不重复,选他可能使得答案变好。
    1. 从前k个项目里选一个项目移除,如果这个项目的类型只出现一次,那么类型数不变,利润数下降,答案不会变好。
    2. 从前k个项目里选一个项目移除,如果这个项目的类型出现多次,那么类型数提高,利润数下降,答案可能会变好。
class Solution {
public:
    long long findMaximumElegance(vector<vector<int>>& items, int k) {
        sort(items.begin(), items.end(), [] (const auto &a, const auto &b) {
            return a[0] > b[0];
        });

        long long res = 0, total_profit = 0;
        unordered_set<int> st;
        stack<int> profit;

        for (int i = 0; i < items.size(); ++i)
        {
            int a = items[i][0], b = items[i][1];
            if (i < k)
            {
                total_profit += a;
                if (st.count(b)) profit.push(a);
                else st.insert(b);
            }
            else if (!profit.empty() && !st.count(b))
            {
                st.insert(b);
                total_profit += a - profit.top();
                profit.pop();
            }
            res = max(res, total_profit + (long long)st.size() * (long long)st.size());
        }
        return res;
    }
};

标签:周赛,dist,int,st,357,vector,&&,return
From: https://www.cnblogs.com/st0rmKR/p/17609549.html

相关文章

  • 【动态规划】【力扣357次周赛】6953. 判断是否能拆分数组
    【力扣357次周赛】6953.判断是否能拆分数组给你一个长度为n的数组nums和一个整数m。请你判断能否执行一系列操作,将数组拆分成n个非空数组。在每一步操作中,你可以选择一个长度至少为2的现有数组(之前步骤的结果)并将其拆分成2个子数组,而得到的每个子数组,至少需......
  • 牛客周赛 Round 5
    牛客周赛Round5A-游游的字母变换_牛客周赛Round5(nowcoder.com)#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signedmain(){ ios::sync_with_stdio(false); cin.tie(nullptr); strings;cin>>s;for(inti=0;i<s.size......
  • LeetCode 周赛上分之旅 # 36 KMP 字符串匹配殊途同归
    ⭐️本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]和BaguTreePro知识星球提问。学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场LeetCode周赛的解题报告,一......
  • 第 356 场周赛 - 力扣(LeetCode)
    第356场周赛-力扣(LeetCode)2798.满足目标工作时长的员工数目-力扣(LeetCode)一次遍历classSolution{public:intnumberOfEmployeesWhoMetTarget(vector<int>&hours,inttarget){intans=0;for(autoi:hours)ans+=......
  • AcWing,第114场周赛-5058双色球
    5058.双色球约翰和贝茜玩抽球游戏。一个盒子中有n个白球和m个黑球。双方轮流行动,由约翰先行。每当轮到一方行动时,其从盒中随机抽出一个球,盒子中的每个球被抽出的概率相同。率先抽出白球的一方获胜。此外,由于贝茜的手比较笨拙,所以每当她抽出一个球后,盒子都会剧烈摇晃,随后就......
  • leetcode第354场周赛 2 - 双指针
    题目传送门2779.数组的最大美丽值题意给你一个数组和一个整数k,数组里面每个数都只能操作一次:加上区间\([-k,k]\)里的数。问你最终由相等元素组成的最长子序列的长度双指针的妙用!思路先排序,前后双指针取差值在2k之间的区间,此区间的所有数均可以操作为同一个属,ans统计最大值......
  • leetcode第109场双周赛
    题目传送门6931.访问数组中的位置使分数最大题意给你一个数组,初始你位于下标1处,你可以往后跳到数组任一下标,但不能往前跳。跳到哪个位置,即可获得下标对应的分数,但如果当前下标的数与跳之前下标的数奇偶性不同,那么你会失去分数x。询问你能获得的最大分数?思路一眼动态规划,......
  • LeetCode 周赛上分之旅 #35 两题坐牢,菜鸡现出原形
    ⭐️本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]和[BaguTreePro]知识星球提问。学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场LeetCode周赛的解题报告......
  • 牛客周赛Round4(java)
     Java组代码importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);intn=scanner.nextInt();intm=scanner.nextInt();StringBuildersb=newStringB......
  • leetcode第 109 场双周赛
    6930.检查数组是否是好的-力扣(LeetCode)首先判断数组长度是不是最大值+1,然后排个序,判断0到n-2是不是都是1到最大值的一个排列,满足这些返回true就行了classSolution{public:boolisGood(vector<int>&num){intma=0;for(autoi:num){......