leetcode第 357/358 场周赛

这篇具有很好参考价值的文章主要介绍了leetcode第 357/358 场周赛。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2817. 限制条件下元素之间的最小绝对差

可能别人有更好的解法,我这写法是不断往线段树中插入数值,每次先插入nums[i-x],然后搜索(1到i)中的最大值和(i到max)中的最小值去更新ans。

class Solution {
public:
    struct node
    {
        int mx,mn;
        int lson,rson;
    };
    int cnt = 1;
    void insert(int pos,int l,int r,int d,vector<node>&tree)
    {
        tree[pos].mx = max(tree[pos].mx,d);
        tree[pos].mn = min(tree[pos].mn,d);
        if(l==r)
            return;
        int mid = (l+r)>>1;
        if(d<=mid)
        {
            if(tree[pos].lson==0)
            {
                tree[pos].lson = cnt++;
                tree[cnt-1].mn = (1<<30);
            }
            insert(tree[pos].lson,l,mid,d,tree);
        }
        else
        {
            if(tree[pos].rson==0)
            {
                tree[pos].rson = cnt++;
                tree[cnt-1].mn = (1<<30);
            }
            insert(tree[pos].rson,mid+1,r,d,tree);
        }
    }
    int getmx(int pos,int l,int r,int L,int R,vector<node>&tree)
    {
        if(L<=l && r<=R)
            return tree[pos].mx;
        int mid = (l+r)>>1;
        int mx = 0;
        if(L<=mid && tree[pos].lson)
            mx = getmx(tree[pos].lson,l,mid,L,R,tree);
        if(mid<R && tree[pos].rson)
            mx = max(mx,getmx(tree[pos].rson,mid+1,r,L,R,tree));
        return mx;
    }
    int getmn(int pos,int l,int r,int L,int R,vector<node>&tree)
    {
        if(L<=l && r<=R)
            return tree[pos].mn;
        int mid = (l+r)>>1;
        int mx = (1<<30);
        if(L<=mid && tree[pos].lson)
            mx = getmn(tree[pos].lson,l,mid,L,R,tree);
        if(mid<R && tree[pos].rson)
            mx = min(mx,getmn(tree[pos].rson,mid+1,r,L,R,tree));
        return mx;
    }
    int minAbsoluteDifference(vector<int>& nums, int x) {
        int tnx=0;
        for(auto i:nums)
            tnx = max(tnx,i);
        vector<node>tree(nums.size()<<5);
        int ans = (1<<30);
        tree[0].mn = (1<<30);
        for(int i=0;i<nums.size();++i)
        {
            if(i-x>=0)
                insert(0,1,tnx,nums[i-x],tree);
            int d = getmx(0,1,tnx,1,nums[i],tree);
            if(d)
                ans = min(ans,nums[i]-d);
            d = getmn(0,1,tnx,nums[i],tnx,tree);
            if(d!=(1<<30))
                ans = min(ans,d-nums[i]);
        }
        return ans;
    }
};

看了看别人题解,直接用set写是真的牛。自己还是见识短浅了。

2813. 子序列最大优雅度

暴力乱搞,考虑两种极端情况,一种无脑选profit大的,一种优先选不同类型的。
我们先选不同类型的,记录值,然后选profit大的没选过的, 更新一下值,然后选完后就会变成profit前k个的情况。取最大值就行。

class Solution {
public:
    bool flag[100010];
    long long findMaximumElegance(vector<vector<int>>& items, int k) {
        sort(items.begin(),items.end(),[](vector<int>&a,vector<int>&b){return a[0]>b[0];});
        map<int,int>mp;
        auto cmp = [](pair<int,int> a,pair<int,int> b){return a.first>b.first;};
        priority_queue<pair<int,int> ,vector<pair<int,int>>,  decltype(cmp)>que(cmp);
        long a=0,b=0;
        int cnt =0;
        long long tp = 0,dc = 0;
        long long ans = 0;
        vector<bool>flag(items.size());
        int num = 0;
        for(int i=0;i<items.size();++i)
        {
           if(dc<k)
           {
                if(!mp[items[i][1]])
                {
                    que.push({items[i][0],items[i][1]});
                    mp[items[i][1]] = 1;
                    dc++;
                    flag[i] = 1;
                    tp+=items[i][0];
                     ans = max(ans,tp+dc*dc);
                     num++;
                }
           }
           else
            break;
        }
        for(int i=0;i<k;++i)
        {
            if(num<k  && flag[i] ==0)
            {
                tp += items[i][0];
                num++;
            }
            else if(!que.empty() && flag[i] ==0)
           {
               auto [a,b] = que.top();
                tp-= a-items[i][0];
                dc--;
                que.pop();
           }
           ans = max(ans,tp+dc*dc);
        }
        return ans;
    }
};

2812. 找出最安全路径

先通过一遍bfs计算出每一个点的安全系数
然后从(0,0)开始跑bfs,每次选择安全系数最大的点,并记录每条路径中最小的安全系数。

class Solution {
public:
    struct node{
        int x,y,val;
        bool operator<(const node &a)const
        {
            return val<a.val;
        }
    };
    int maximumSafenessFactor(vector<vector<int>>& grid) {
        int n = grid.size();
        int m = grid[0].size();
        vector dis(n,vector<int>(m,(1<<30)));
        queue<pair<int,int>>q;
        for(int i=0;i<n;++i)
            for(int j=0;j<m;++j)
                if(grid[i][j])
                {
                    dis[i][j] = 0;
                    q.push({i,j});
                }
        int f[] = {0,-1,0,1,1,0,-1,0};
        while(!q.empty())
        {
            auto [x,y] = q.front();
            q.pop();
            for(int i=0;i<4;++i)
            {
                int nx = x+f[i<<1];
                int ny = y+f[i<<1|1];
                if(nx>=0 && nx<n && ny>=0 &&ny<m)
                {
                    if(dis[nx][ny]>dis[x][y]+1)
                    {
                        dis[nx][ny] = dis[x][y]+1;
                        q.push({nx,ny});
                    }
                }
            }
        }
        vector cost(n,vector<int>(m,0));
        vector flag(n,vector<bool>(m,0));
        priority_queue<node>que;
        que.push({0,0,dis[0][0]});
        cost[0][0] = dis[0][0];
        while(!que.empty())
        {
            auto u = que.top();
            que.pop();
            if(flag[u.x][u.y])
                continue;
            flag[u.x][u.y] = 1;
            for(int i=0;i<4;++i)
            {
                int nx = u.x+f[i<<1];
                int ny = u.y+f[i<<1|1];
                if(nx>=0 && nx<n && ny>=0 &&ny<m)
                {
                    if(cost[nx][ny]<cost[u.x][u.y] && !flag[nx][ny])
                    {
                        cost[nx][ny] = min(cost[u.x][u.y],dis[nx][ny]);
                        que.push({nx,ny,dis[nx][ny]});
                    }
                }
            }
        }
        return cost[n-1][n-1];
            
    }
};

2818. 操作使得分最大

统计每一个数字的最大区间 [ L , R ] [L,R] [L,R],满足当 L < = l < = i 且 i < = r < = R L<=l<=i 且 i<=r<=R L<=l<=ii<=r<=R时,该区间的分数为 n u m s [ i ] nums[i] nums[i],这个区间使用单调栈统计,然后每个 n u m [ i ] num[i] num[i]可以被使用次数就为 ( i − L + 1 ) ∗ ( R − i + 1 ) (i-L+1)*(R-i+1) (iL+1)(Ri+1)。最后把数字从大到小排序,然后选择k个即可。文章来源地址https://www.toymoban.com/news/detail-656714.html

class Solution {
public:
    const int mod = 1e9+7;
    int maximumScore(vector<int>& nums, int k) {
        vector<int> score(nums.size());
        auto calscore = [](int a){
            int ret = 0;
            for(int i=2;i*i<=a;++i)
            {
                if(a%i==0)
                {
                    ret++;
                    while(a%i==0)
                        a/=i;
                }
            }
            if(a!=1)
                ret++;
            return ret;
        } ;
        for(int i=0;i<nums.size();++i)
            score[i] = calscore(nums[i]);
        vector<int>pre(nums.size());
        vector<int>sa(nums.size(),nums.size());
        stack<int>ddz;
        for(int i=0;i<nums.size();++i)
        {
            while(!ddz.empty() && score[i]>score[ddz.top()])
            {
                sa[ddz.top()] = i;
                ddz.pop();
            }
            if(ddz.empty())
                pre[i] = -1;
            else 
                pre[i] = ddz.top();
            ddz.push(i);
        }
        auto cmp = [](pair<int,long long>a,pair<int,long long>b)
        {
            if(a.first==b.first)
                return a.second<b.second;
            return a.first<b.first;
        };
        priority_queue< pair<int,long long>, vector<pair<int,long long> > , decltype(cmp) > que(cmp);
        for(int i=0;i<nums.size();++i)
        {
            que.push({nums[i],(sa[i]-i)*(i-pre[i])});
        }
        long long ans = 1;
        auto qpow = [=](long long a,long long b)->long long
        {
            long long ret = 1;
            while(b)
            {
                if(b&1) ret = (a*ret)%mod;
                a = a*a%mod;
                b>>=1;
            }
            return ret;
        };
        while(k)
        {
            
            auto [x,y] = que.top();
            que.pop();
            ans = ans*qpow(x,min(y,1ll*k))%mod;
            k -= min(y,1ll*k);
            
        }
        return ans;
    }
};

到了这里,关于leetcode第 357/358 场周赛的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【LeetCode周赛】LeetCode第359场周赛

    给你一个字符串数组 words 和一个字符串 s ,请你判断 s 是不是 words 的 首字母缩略词 。 如果可以按顺序串联 words 中每个字符串的第一个字符形成字符串 s ,则认为 s 是 words 的首字母缩略词。例如,“ab” 可以由 [“apple”, “banana”] 形成,但是无法从 [“bear”, “aardvark”

    2024年02月10日
    浏览(8)
  • 【LeetCode周赛】LeetCode第370场周赛

    【LeetCode周赛】LeetCode第370场周赛

    一场比赛中共有 n 支队伍,按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 = i, j = n - 1 且 i != j 的所有 i, j :如果 grid[i][j] == 1,那么 i 队比 j 队 强 ;否则,j 队比 i 队 强 。 在这场比赛中,如果不存在某支强于 a 队的队伍,则认为

    2024年02月05日
    浏览(10)
  • [LeetCode周赛复盘] 第 348场周赛20230604

    [LeetCode周赛复盘] 第 348场周赛20230604

    这场可惜了。 T1 模拟。 T2 模拟。 T3 倒序计算。 T4 同时限制上下界的数位DP。 6462. 最小化字符串长度 1. 题目描述 2. 思路分析 题意仔细想一下就会发现,其实会将每个字符仅留1个。 3. 代码实现 6424. 半有序排列 1. 题目描述 2. 思路分析 由于只能相邻交换来移动,因此每次只能

    2024年02月08日
    浏览(20)
  • [LeetCode周赛复盘] 第 359 场周赛20230820

    [LeetCode周赛复盘] 第 359 场周赛20230820

    T1 模拟。 T2 数学贪心。 T3 dp。 T4 分组+滑窗。 2828. 判别首字母缩略词 1. 题目描述 2. 思路分析 按题意模拟即可。 3. 代码实现 2829. k-avoiding 数组的最小总和 1. 题目描述 2. 思路分析 贪心 1~k-1中,选了1就不能选k-1;选了2就不能选k-2… 因此可以选1~k//2 剩余的从k开始向上选。 可以

    2024年02月11日
    浏览(17)
  • [LeetCode周赛复盘] 第 353 场周赛20230709

    [LeetCode周赛复盘] 第 353 场周赛20230709

    感觉有奖品大家都来了。 T1 数学。 T2 dp。 T3 dp。 T4 差分/BIT RUPQ。 6451. 找出最大的可达成数字 1. 题目描述 2. 思路分析 为了使x num在t步内相同,需要相向而行,每步最大缩短距离是2,那么t步距离是2t。 3. 代码实现 6899. 达到末尾下标所需的最大跳跃次数 1. 题目描述 2. 思路分

    2024年02月15日
    浏览(9)
  • leetcode 第360场周赛

    好久没参加leetcode周赛了,比赛时间都从两小时变成了一个半小时。这次周赛由两道签到题和两道中等难度题组成,严格来说最后一道的难度也可以视为hard,但是只要想到正确的思路,编码还是比较容易的。 比赛链接:leetcode 第 360 场周赛 题目描述 给你一个长度为 n 的字符串

    2024年02月11日
    浏览(12)
  • LeetCode第343场周赛

    2023.4.30LeetCode第343场周赛 根据题意模拟 使用哈希表记录每个数出现的位置,再用m+n个集合记录每一行和每一列被涂满的格子数,若某行或某列全部被涂满则返回答案 BFS 首先将距离大于两点的曼哈顿距离的特殊路径去掉 每个点考虑经过每个特殊路径到达,分成两段,一段是当

    2024年02月02日
    浏览(12)
  • LeetCode第347场周赛

    2023.5.28LeetCode第347场周赛 从最后一位开始遍历,为0则跳过 暴力模拟 对于每个 s[i] != s[i - 1] ,要使其相等 有两种选择,翻转前 i 个,或者翻转后 n - i 个,选择代价最小的方案 动态规划 从小到大枚举所有值,每个值一定是从更小的数转移而来 定义动态规划数组f, f[i][j] 表示

    2024年02月06日
    浏览(10)
  • LeetCode第354场周赛

    给你一个下标从 1 开始、长度为 n 的整数数组 nums 。 对 nums 中的元素 nums[i] 而言,如果 n 能够被 i 整除,即 n % i == 0 ,则认为 num[i] 是一个 特殊元素 。 返回 nums 中所有 特殊元素 的 平方和 。 直接模拟就好了 给你一个下标从 0 开始的整数数组 nums 和一个 非负 整数 k 。 在一

    2024年02月16日
    浏览(14)
  • Leetcode 第 365 场周赛题解

    Leetcode 第 365 场周赛题解

    思路 暴力。 代码 复杂度分析 时间复杂度:O(n 3 ),其中 n 是数组 nums 的长度。 空间复杂度:O(1)。 思路 枚举 k,我们需要知道 k 左边 nums[i]−nums[j] 的最大值。 使用 pre_max 维护 k 之前的 nums[i] 的最大值,使用 max_diff 维护 nums[i]−nums[j] 的最大值。 每次遍历一个 nums[i],都更新

    2024年02月07日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包