首页 > 其他分享 >第308场周赛

第308场周赛

时间:2022-09-20 14:34:39浏览次数:86  
标签:308 周赛 nums int 复杂度 far vector ans

这次差两分钟做出最后一道题

第308场周赛

2389. 和有限的最长子序列

我用的双重循环,时间复杂度挺高的,但是蛮有意思的哈哈哈

class Solution {
public:
    vector<int> answerQueries(vector<int>& nums, vector<int>& query) {
        vector<int> ans;
        sort(nums.begin(), nums.end());
        for(auto val : query){
            int st = 0, sum = 0, res = 0;
            for(int i = 0; i < nums.size(); i++){
                sum += nums[i];
                while(sum > val){
                    sum -= nums[st];
                    ++st;
                }
                res = max(res, i - st + 1);
            }
            ans.push_back(res);
        }
        return ans;
    }
};

(贪心,前缀和,二分) \(O((n+m)logn)\)

  • 显然选择的数字越小最终的子集和也就会尽可能小。

  • 可以先把 nums 数组从小到大排序,然后对于每个询问 qq,二分查找第一个大于 qq 的前缀和位置 pp 作为答案。

时间复杂度

  • 排序的时间复杂度为 O(nlogn)。
  • 排序后,每个询问二分的时间复杂度为 O(logn)。
  • 故总时间复杂度为 O((n+m)logn)。

空间复杂度

需要 O(m+logn)的额外空间存储答案以及排序的递归系统栈。

class Solution {
public:
    vector<int> answerQueries(vector<int>& nums, vector<int>& queries) {
        const int n = nums.size();

        sort(nums.begin(), nums.end());

        for (int i = 1; i < n; i++)
            nums[i] += nums[i - 1];

        vector<int> ans;

        for (int q : queries)
            ans.push_back(upper_bound(nums.begin(), nums.end(), q) - nums.begin());

        return ans;
    }
};

2390. 从字符串中移除星号

使用栈进行模拟,遇到*出栈,其他的进栈

时间复杂度

字符串扫描一遍,时间复杂度\(O(N)\)

空间复杂度

需要额外的和s一样长的空间,时间复杂度是\(O(N)\)

代码

const int N = 1e5 + 10;
char s[N];
class Solution {
public:
    string removeStars(string str) {
        int top = -1;
        for(char &c : str){
            if(c == '*') --top;
            else s[++top] = c;
        }
        string ans = "";
        for(int i = 0; i <= top; i++)
            ans += s[i];
        return ans;
    }
};

2391. 收集垃圾的最少总时间

(模拟) O(nL)

  1. 答案可以拆分成所有房子的垃圾数量总和,再加上每辆垃圾车行驶到的最后一个房子的距离。
  2. 遍历所有房子的垃圾,找到每种垃圾最后出现的房子的位置。

时间复杂度

遍历所有房子的垃圾,故时间复杂度为 O(nL)

空间复杂度

仅需要常数的额外空间。

class Solution {
public:
    int garbageCollection(vector<string>& gar, vector<int>& tra) {
        int n = gar.size();
        int ans = 0, metal_far = 0, paper_far = 0, glass_far = 0;
        
        for(int i = 0; i < n; i++){
            ans += gar[i].size();
            for(auto c : gar[i]){
                if(c == 'M')  metal_far = i;
                else if(c == 'P') paper_far = i;
                else  glass_far = i;
            }
        }
        
        for(int i = 1; i < n - 1; i++) tra[i] += tra[i - 1];
        if(metal_far > 0) ans += tra[metal_far - 1];
        if(paper_far > 0) ans += tra[paper_far - 1];
        if(glass_far > 0) ans += tra[glass_far - 1];
        return ans;
    }
};

2392. 给定条件下构造矩阵

(拓扑排序) O(k+m)

  1. 分别对行和列进行拓扑排序,求出每个数字所在的排名。
  2. 如果拓扑排序不存在,则说明答案不存在。
  3. 按照行和列的排名填充最终的矩阵。

时间复杂度

两次拓扑排序的时间复杂度为 O(k+m),其中 m 为条件的长度。
填充答案仅需要 O(k) 的时间。(忽略新建 \(k^2\) 零矩阵的时间。)

空间复杂度

需要 \(O(k^2)\) 的额外空间存储拓扑排序的数据结构和答案。

class Solution {
public:
    vector<int> topSort(int k, vector<vector<int>>& condition){
        vector<vector<int>> son(k + 1);
        vector<int> in(k + 1);
        
        for(auto &c : condition){
            int a = c[0], b = c[1];
            son[a].push_back(b);
            ++in[b];
        }
        
        vector<int> q(410);
        int hh = 0, tt = -1;
        
        for(int i = 1; i <= k; i++)
            if(!in[i])
                q[++tt] = i;
        
        while(hh <= tt){
            int t = q[hh++];
            for(int u : son[t])
                if(!--in[u])
                    q[++tt] = u;
        }
        if(tt != k - 1) return {};
        return q;
    }
    
    int get(vector<int> &w, int t){
        for(int i = 0; i < w.size(); i++)
            if(w[i] == t)
                return i;
        return 0;
    }
    
    vector<vector<int>> buildMatrix(int k, vector<vector<int>>& row, vector<vector<int>>& col) {
        auto r = topSort(k, row), c = topSort(k, col);
        if(r.size() < k || c.size() < k) return {};
        vector<vector<int>> ans(k, vector<int>(k));
        for(int i = 1; i <= k; i++)
            ans[get(r, i)][get(c, i)] = i;
        return ans;
    }
};

标签:308,周赛,nums,int,复杂度,far,vector,ans
From: https://www.cnblogs.com/INnoVationv2/p/16710938.html

相关文章

  • # 87双周赛
    这次只做出了三道题6184.统计共同度过的日子数不熟悉api,没用过sscanf,在处理日期字符串的时候耽误了很多时间,最后用的substr()和stoi(stoi还是现场在网上搜的,哈哈哈)......
  • 2022-2023-1 20221308 《计算机基础与程序设计》第三周学习总结
    作业信息班级的链接:https://edu.cnblogs.com/campus/besti/2022-2023-1-CFAP作业要求的链接:https://www.cnblogs.com/rocedu/p/9577842.html#WEEK03教材学习内容总结《c......
  • acwing第67场周赛
    1.火柴棍数字原题链接:https://www.acwing.com/problem/content/4612/思路利用n根火柴拼成最大的数字数字位数越大,数字的值就越大1只用两根火柴就可以拼成,所以就看n根......
  • acwing第66场周赛
    1.判断奇偶原题链接:https://www.acwing.com/problem/content/4609/判断就就直接%2即可#include<iostream>usingnamespacestd;intmain(){strings;fo......
  • 第 66 场周赛
    A奇偶判断intmain(){ strings;cin>>s; intx=s[6]-'0'; if(x%2)cout<<1<<endl; elsecout<<0<<endl; return0;}B字母补全思路:依次枚......
  • 信息学一本通 1308:【例1.5】高精除
    时间限制:1000ms      内存限制:65536KB提交数:14866   通过数:7293【题目描述】高精除以高精,求它们的商和余数。【输入】输入两个低于300位......
  • AcWing杯 - 第66场周赛
    比赛链接:[第66场周赛](竞赛-AcWing)先放代码,题解慢慢补AAcWing4606.奇偶判断#include<set>#include<map>#include<queue>#include<stack>#include<cmath>#i......
  • Acwing 第 66 场周赛 A-C
    2A,来晚+中间有事,第三题没写,但是写第三题的时候也感觉犯迷糊,读懂题意就好了AAcWing4606.奇偶判断题意:判断末位是偶数还是奇数跳过 BAcWing4607.字母补全题意......
  • 第 66 场周赛 ABC
    A-奇偶判断#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<int,int>PII;constLLN=200200;LLa[N],b[N];#definexfirst#defi......
  • 启动项目报错:Error: error:0308010C:digital envelope routines::unsupported
    启动项目报错信息如下:Error:error:0308010C:digitalenveloperoutines::unsupportedatnewHash(node:internal/crypto/hash:71:19)atObject.createHash(nod......