113双周赛

news2024/11/20 6:12:32

题目列表

2855. 使数组成为递增数组的最少右移次数

2856. 删除数对后的最小数组长度

2857. 统计距离为 k 的点对

2858. 可以到达每一个节点的最少边反转次数

一、使数组成为递增数组的最少右移次数

这题可以直接暴力求解,枚举出每种右移后的数组,将它和排完序后的数组比较,时间复杂度为O(n^2)

代码如下

class Solution {
public:
    int minimumRightShifts(vector<int>& nums) {
        vector<int> v=nums;
        sort(v.begin(),v.end());
        for(int i=0;i<nums.size();i++){
            if(v==nums) return i;
            nums.insert(nums.begin(),nums.back());
            nums.pop_back();
        }
        return -1;
    }
};

这个能过,但是有没有更快的算法,我们观察一下这个数组,如果它要是能右移成递增数组,那么它必然是由两个递增数组构成的,且前一个数组的最小值,一定大于后一个数组的最大值,答案就是第二个数组的长度,所以我们只要试着将数组拆分成两个递增数组就行(边界条件挺多,一定要细节),时间复杂度为O(n)

代码如下

class Solution {
public:
    int minimumRightShifts(vector<int>& nums) {
        int end1=0,n=nums.size();
        while(end1+1<n&&nums[end1]<nums[end1+1])
            end1++;
        if(end1==n-1) return 0;
        int end2=end1+1;
        while(end2+1<n&&nums[end2]<nums[end2+1])
            end2++;
        if(end2!=n-1||nums[0]<nums[n-1]) return -1;
        else return n-end1-1;
    }
};

二、删除数对后的最小数组长度

这题还是比较难想到的,比较绕。我们需要多枚举几个例子,然后就会发现,当某个数的个数cnt大于等于数组长度n的一半时,最优的方案就是将它前后的数都与它相互抵消(因为如果还让其他数相互抵消,那么剩余的和该数相抵消的元素个数就会变小,从而该元素剩下的个数就会变多),所以答案就是cnt-(n-cnt)=2*cnt-n,那么如果没有一个数的个数大于数组长度的一半呢?

首先从最特殊的数组中数字都是唯一的情况开始讨论,那么显然,当数组长度为偶数时,答案为0,当数组长度为奇数时,答案为1,那么是不是所有的情况都符合这个规律呢?答案是,确实都符合这个规律,因为所有的数的个数都<n/2,那么我们就可以通过抵消,将数的个数全部化成1

代码如下

class Solution {
public:
    int minLengthAfterRemovals(vector<int>& nums) {
        unordered_map<int,int>cnt;
        int n=nums.size(),ans=n&1;//n&1,奇数为1,偶数为0
        for(auto x:nums)
            ++cnt[x];
        for(auto [x,y]:cnt)
            if(y>n/2)
                ans=max(ans,2*y-n);
        return ans;
    }
};

当然这题如果想不到这么深,那么也可以用最基本的贪心,每次拿出出现次数最大的两个元素相抵消,直到剩下零个数或剩下一个数为止。代码如下

class Solution {
public:
    int minLengthAfterRemovals(vector<int>& nums) {
        unordered_map<int,int>cnt;
        int n=nums.size(),ans=n&1;
        for(auto x:nums)
            ++cnt[x];
        priority_queue<int>q;
        for(auto [x,y]:cnt)
            q.push(y);
        while(q.size()>1){
            int x=q.top();q.pop();
            int y=q.top();q.pop();
            x--,y--;
            if(x)q.push(x);
            if(y)q.push(y);
        }
        return q.empty()?0:q.top();
    }
};

三、统计距离为k的点对

看到两个数的和k,以及k的数据范围,我们就要想到这题能用暴力枚举点来做,然后通过枚举到的点,求出与之相对应的点的坐标,答案加上之前出现的该点个数(用哈希表统计),代码如下

class Solution {
public:
    int countPairs(vector<vector<int>>& coordinates, int k) {
        int n=coordinates.size();
        unordered_map<long long,int>cnt;
        int ans=0;
        for(auto& e:coordinates){
            int x=e[0],y=e[1];
            for(int i=0;i<=k;i++){
                auto it=cnt.find((x^i)*1000000LL+(y^(k-i)));
                if(it!=cnt.end())
                    ans+=it->second;
            }
            cnt[x*1000000LL+y]++;
        }
        return ans;
    }
};

 四、可以到达每一个节点的最小边反转次数

这题是换根dp,即通过根节点的最小边反转次数,来得到它孩子结点的最小边反转次数,因为它的孩子结点的反转边的个数就和它父节点的最小边反转次数相差一个它俩之间的边是否需要翻转,其它的都一样。

代码如下

class Solution {
public:
    vector<int> minEdgeReversals(int n, vector<vector<int>>& edges) {
        //建图
        vector<vector<pair<int,int>>>g(n);
        for(auto& e:edges){
            int x=e[0],y=e[1];
            g[x].push_back({y,1});//顺便记录一下边的方向,1为正,-1为逆
            g[y].push_back({x,-1});
        }

        vector<int>ans(n);
        //计算根节点的最少边反转次数
        function<void(int,int)>dfs=[&](int x,int fa){
            for(auto& [y,dir]:g[x]){
                if(y!=fa){
                    ans[0]+=(dir<0);//方向反的需要反转
                    dfs(y,x);
                }
            }
        };
        dfs(0,-1);

        //换根dp
        function<void(int,int)>reroot=[&](int x,int fa){
            for(auto& [y,dir]:g[x]){
                if(y!=fa){
                    ans[y]=ans[x]+dir;
                    reroot(y,x);
                }
            }
        };
        reroot(0,-1);
        return ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1035421.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL学习笔记4

客户端工具的使用&#xff1a; MySQL&#xff1a; mysql命令行工具&#xff0c;一般用来连接访问mysql的数据。 案例&#xff1a;使用mysql客户端工具连接服务器端&#xff08;用户名&#xff1a;root&#xff1b;密码&#xff1a;123456&#xff09;. [rootmysql-server ~]#…

不甘于被强势厂商捆绑,中国移动未来或自研5G基站

一直以来运营商被认为只是做服务&#xff0c;而设备等都是由设备商提供的&#xff0c;甚至由于如今的设备高度复杂&#xff0c;设备商已承包越来越多的基站运维工作&#xff0c;运营商的技术水平越来越低&#xff0c;不过随着中国移动发布5G射频芯片8676&#xff0c;似乎显示出…

centos7用docker安装WireGuard教程

1、 检查centos内核版本 uname -r2、升级内核 下载脚本上传到服务器运行脚本进行升级内核 链接&#xff1a;https://pan.baidu.com/s/1vYmqVy2St3nFnJWGPIwdOw 提取码&#xff1a;owac 3、安装WireGuard 方案一&#xff1a;使用脚本安装 执行第二步脚本进行安装#启动wg0wg…

CSRF攻击(跨站请求伪造)

1.CSRF原理 程序员开发的时候&#xff0c;未对相关页面进行token和referer判断&#xff0c;造成攻击者可构造自己的URL地址欺骗用户进行点击 漏洞分析&#xff08;低级可绕过&#xff09; 通过这个可以更改密码 改为了password 中级多了referer头可以绕过 源代码 多了一个refer…

简单好用的Python装饰器详解

装饰器&#xff08;Decorators&#xff09;是Python中一种强大而灵活的功能&#xff0c;用于修改或增强函数或类的行为。装饰器本质上是一个函数&#xff0c;它接受另一个函数或类作为参数&#xff0c;并返回一个新的函数或类。它们通常用于在不修改原始代码的情况下添加额外的…

linux服务器加固-密码验证设置

安全问题 安全控制点 风险分析 风险等级 标准要求 查看登录/etc/login.defs文件PASS_MAX_DAYS参数为99999&#xff0c;查看/etc/pam.d/system-auth文件&#xff0c;未对密码策略进行有效配置&#xff0c;如&#xff1a;密码更换周期&#xff0c;密码是否包括字母、数字与特…

基于SpringBoot的网上点餐系统

目录 前言 一、技术栈 二、系统功能介绍 用户功能模块 管理员功能模块 美食店功能模块 前台首页功能模块 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 系统管理也都将通过计算机进行整体智能化操作&#xff0c;对于网上点餐系统所牵扯的管理及数据保存…

【从0学习Solidity】 32. 代币水龙头

【从0学习Solidity】32. 代币水龙头 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#xff0c;探索全…

兴达易控EtherCAT转Modbus网关用Modbus Slave模拟从站配置案例

兴达易控EtherCAT到Modbus网关可以用作Modbus从站的配置。EtherCAT到Modbus网关允许Modbus协议转换为EtherCAT&#xff0c;实现不同通信系统之间的互操作性。通过配置从站到网关的Modbus&#xff0c;您可以访问和控制Modbus设备。同时&#xff0c;网关还可以扩展Modbus网络的范…

[C++基础]-继承

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 目录 一、模板的…

2023-9-23 最大不相交区间数量

题目链接&#xff1a;最大不相交区间数量 #include <iostream> #include <algorithm>using namespace std;const int N 100010;int n;struct Range {int l, r;bool operator< (const Range &W) const {return r < W.r;} }range[N];int main() {cin >…

Unity中的两种ScriptingBackend

一&#xff1a;前言 二&#xff1a;两种模式的介绍 ios&#xff1a;unity只有il2cpp模式的编译才支持64位系统&#xff0c;mono是不支持的&#xff0c;在快速开发阶段仍然支持Mono&#xff0c;但是不能再向Apple提交Mono(32位)的应用 苹果在2016年1月就要求所有新上架游戏必须支…

ASO优化之竞争对手的选择取决于什么

任何具有良好ASO策略的应用程序都是来自于良好的基准&#xff0c;不仅可以对市场有总体概述&#xff0c;还可以发现应用的增长潜力以及如何在不同的应用商店中获得知名度。在发布应用之前&#xff0c;需要制定ASO策略以获得搜索和浏览可见性&#xff0c;所以研究竞争对手是基础…

【小沐学NLP】关联规则分析Apriori算法(Mlxtend库,Python)

文章目录 1、简介2、Mlxtend库2.1 安装2.2 功能2.2.1 User Guide2.2.2 User Guide - data2.2.3 User Guide - frequent_patterns 2.3 入门示例 3、Apriori算法3.1 基本概念3.2 apriori3.2.1 示例 1 -- 生成频繁项集3.2.2 示例 2 -- 选择和筛选结果3.2.3 示例 3 -- 使用稀疏表示…

Klocwork 2023.2 windows

Klocwork 2023.2 windows 2692407267qq.com&#xff0c;更多内容请见http://user.qzone.qq.com/2692407267/

es6新语法特性+vue2的学习笔记

1. es6 ECMA的第6版&#xff0c;15年发布&#xff0c;规定新的语法特性 2. let声明变量 varlet声明的变量会越狱声明的变量有严格的作用域可以声明多次只能声明一次会变量提升(未声明的变量不会报错)不会变量提升 代码案例&#xff1a; <script>// {// var a 1;/…

点分治维护dp+连通块上新型dp思路+乘积方面进行根号dp:0922T4

首先连通块&#xff0c;所以点分治肯定是 Trick1 钦定选根的连通块dp 对于钦定选根的连通块dp&#xff0c;有一种常见思路 先对原树求其dfn序&#xff0c;按dfn序倒序求解 具体的&#xff0c;对于当前点 i i i&#xff08;注意这里都是指dfn序&#xff09;&#xff0c;我们…

如何申请办理400电话?

导语&#xff1a;随着企业的发展和市场竞争的加剧&#xff0c;越来越多的企业开始意识到拥有一个400电话的重要性。本文将介绍如何申请办理400电话&#xff0c;帮助企业提升客户服务质量和品牌形象。 一、了解400电话的概念和优势 400电话是一种企业客服电话号码&#xff0c;…

描述符——设备描述符

文章目录 描述符定义描述符实现描述符含义 描述符定义 描述符实现 /*** brief Device descriptor.*/ typedef struct __attribute__ ((packed)) {uint8_t bLength ; /**< Size of this descriptor in bytes. */uint8_t bDescriptorType ; /**< DEVICE D…