力扣周赛:第414场周赛

news2024/11/16 7:46:33

👨‍🎓作者简介:爱好技术和算法的研究生
🌌上期文章:[首期文章]
📚订阅专栏:力扣周赛
希望文章对你们有所帮助

本科打ACM所以用的都是C++,未来走的是Java,所以现在敲算法还是主要Java为主,C++偶尔敲一下保持一下记忆。

力扣周赛:第414场周赛

  • 将日期转换为二进制表示
  • 范围内整数的最大得分
  • 到达数组末尾的最大得分
  • 吃掉所有兵需要的最多移动次数

将日期转换为二进制表示

题目描述
给你一个字符串 date,它的格式为 yyyy-mm-dd,表示一个公历日期。

date 可以重写为二进制表示,只需要将年、月、日分别转换为对应的二进制表示(不带前导零)并遵循 year-month-day 的格式。

返回 date 的 二进制 表示。
示例1
输入: date = “2080-02-29”

输出: “100000100000-10-11101”

解释:

100000100000, 10 和 11101 分别是 2080, 02 和 29 的二进制表示。
示例2
输入: date = “1900-01-01”

输出: “11101101100-1-1”

解释:

11101101100, 1 和 1 分别是 1900, 1 和 1 的二进制表示。

签到题,不必多说

class Solution {
    public String convertDateToBinary(String date) {
        String[] dates = date.split("-");
        String ans = "";
        for(int i = 0;i < 3; ++i){
            if(i != 0){
                ans += "-";
            }
            int num = 0, n = dates[i].length();
            String res = "";
            for(int j = 0; j < n; ++j){
                num = num * 10 + dates[i].charAt(j) - '0';
            }
            while(num != 0){
                if((num & 1) == 1){
                    res += "1";
                }
                else res += "0";
                num >>= 1;
            }
            StringBuffer sb = new StringBuffer(res);
            res = sb.reverse().toString();
            ans += res;
        }
        return ans;
    }
}

范围内整数的最大得分

题目描述
给你一个整数数组 start 和一个整数 d,代表 n 个区间 [start[i], start[i] + d]

你需要选择 n 个整数,其中第 i 个整数必须属于第 i 个区间。所选整数的 得分 定义为所选整数两两之间的 最小 绝对差。

返回所选整数的 最大可能得分
示例1
输入: start = [6,0,3], d = 2

输出: 4

解释:

可以选择整数 8, 0 和 4 获得最大可能得分,得分为 min(|8 - 0|, |8 - 4|, |0 - 4|),等于 4。
示例2
输入: start = [2,6,13,13], d = 5

输出: 5

解释:

可以选择整数 2, 7, 13 和 18 获得最大可能得分,得分为 min(|2 - 7|, |2 - 13|, |2 - 18|, |7 - 13|, |7 - 18|, |13 - 18|),等于 5。

数据范围
2 <= start.length <= 105
0 <= start[i] <= 109
0 <= d <= 109

d的范围如此大,只要一次循环就必定会超时,但是对于每个数字,我们必定需要对[0, d]之间的范围进行相加,因此很显然这题需要使用二分,因此我们只需要对答案进行二分,重点是二分的条件判断。观察样例可以很容易发现,最小的数一定不会继续增大,而最大的数会增大到最大即+d,这样有助于得到最大得分,另外可以发现位置并不影响最终的结果,因此可以直接将数组进行排序。

对于特定得分score,判断是否可以使所选整数的得分不小于 score 的方法如下:遍历按升序排序的数组 start,遍历过程中维护上一个选择的整数 prev,初始时 prev=−∞,对于遍历到的每个整数 num,执行如下操作:

  • 如果num+d−prev<score,则即使当前选择的整数取最大值也不满足与上一个选择的整数之差大于等于 score,因此无法使所选整数的得分不小于 score。
  • 如果num+d−prev≥score,则当前选择的整数可以取的最小值为 max(num,prev+score),将 prev 的值更新,然后继续遍历其余元素

上述做法中,对于遍历到的每个整数都计算选择的整数可以取的最小值,该做法基于贪心策略,理由如下:后一个整数的取值范围根据数组 start 中的元素值与整数 d 确定,当后一个选择的整数的取值范围确定时,前一个整数的取值越小,后一个整数可以选择的范围越大,如果前一个整数的取值大于可以取的最小值,则后一个整数可以选择的范围更小,该选择整数的方案一定不会优于取最小值的方案。

代码如下:

class Solution {
    public int maxPossibleScore(int[] start, int d) {
        Arrays.sort(start);
        long l = 0, r = start[start.length - 1] + d - start[0];
        int res = 0;
        while(l <= r){
            long mid = (l + r) >> 1;
            int flag = 0; long prev = Integer.MIN_VALUE;
            for(int i = 0; i < start.length; ++i){
                if(start[i] + d - prev < mid){
                    flag = 1;
                    break;
                }
                prev = Math.max(start[i], prev + mid);
            }
            if(flag == 1)r = mid - 1;
            else{
                l = mid + 1;
                res = (int)mid;
            }
        }
        return res;
    }
}

到达数组末尾的最大得分

题目描述
给你一个长度为 n 的整数数组 nums 。

你的目标是从下标 0 出发,到达下标 n - 1 处。每次你只能移动到 更大 的下标处。

从下标 i 跳到下标 j 的得分为 (j - i) * nums[i]

请你返回你到达最后一个下标处能得到的 最大总得分 。
示例1
输入:nums = [1,3,1,5]

输出:7

解释:

一开始跳到下标 1 处,然后跳到最后一个下标处。总得分为 1 * 1 + 2 * 3 = 7 。
示例2
输入:nums = [4,3,1,3,2]

输出:16

解释:

直接跳到最后一个下标处。总得分为 4 * 4 = 16 。
数据范围
1 <= nums.length <= 105
1 <= nums[i] <= 105

很显然是贪心,直接遍历数组,只要发现更大的nums[i]就停止,并计算在此之前的总得分,最后重新更新这个最大的数,直到遍历完这个数组,力扣上有一个题解是将其比喻为长方形面积,还是很形象的,这里借鉴一下

在这里插入图片描述
代码如下:

class Solution {
    public long findMaximumScore(List<Integer> nums) {
        long ans = 0, maxn = nums.get(0), pos = 0;
        for(int i = 1; i < nums.size(); ++i){
            if(nums.get(i) > maxn){
                ans += (i - pos) * maxn;
                maxn = nums.get(i);
                pos = i;
            }
        }
        ans += (nums.size() - pos - 1) * maxn;
        return ans;
    }
}

吃掉所有兵需要的最多移动次数

题目描述
给你一个 50 x 50 的国际象棋棋盘,棋盘上有 一个 马和一些兵。给你两个整数 kx 和 ky ,其中 (kx, ky) 表示马所在的位置,同时还有一个二维数组 positions ,其中 positions[i] = [xi, yi] 表示第 i 个兵在棋盘上的位置。

Alice 和 Bob 玩一个回合制游戏,Alice 先手。玩家的一次操作中,可以执行以下操作:

玩家选择一个仍然在棋盘上的兵,然后移动马,通过 最少 的 步数 吃掉这个兵。注意 ,玩家可以选择 任意 一个兵,不一定 要选择从马的位置出发 最少 移动步数的兵。
在马吃兵的过程中,马 可能 会经过一些其他兵的位置,但这些兵 不会 被吃掉。只有 选中的兵在这个回合中被吃掉。
Alice 的目标是 最大化 两名玩家的 总 移动次数,直到棋盘上不再存在兵,而 Bob 的目标是 最小化 总移动次数。

假设两名玩家都采用 最优 策略,请你返回 Alice 可以达到的 最大 总移动次数。

在一次 移动 中,如下图所示,马有 8 个可以移动到的位置,每个移动位置都是沿着坐标轴的一个方向前进 2 格,然后沿着垂直的方向前进 1 格。
在这里插入图片描述

示例1
输入:kx = 1, ky = 1, positions = [[0,0]]

输出:4

解释:马需要移动 4 步吃掉 (0, 0) 处的兵。
示例2
输入:kx = 0, ky = 2, positions = [[1,1],[2,2],[3,3]]

输出:8

解释:

  • Alice 选择 (2, 2) 处的兵,移动马吃掉它需要 2 步:(0, 2) -> (1, 4) -> (2, 2) 。
  • Bob 选择 (3, 3) 处的兵,移动马吃掉它需要 2 步:(2, 2) -> (4, 1) -> (3, 3) 。
  • Alice 选择 (1, 1) 处的兵,移动马吃掉它需要 4 步:(3, 3) -> (4, 1) -> (2, 2) -> (0, 3) -> (1, 1) 。

这道题没做出来,贴一个我觉得比较不错的题解:题解
总的来说就是DP+递推/记忆化搜索

代码如下(借鉴AC代码):

class Solution {
    private static final int[][] dirs = {
        {2, 1}, {1, 2}, {-1, 2}, {-2, 1},
        {-2, -1}, {-1, -2}, {1, -2}, {2, -1}
    };
    public int maxMoves(int kx, int ky, int[][] positions) {
        int n = positions.length;
        int[][][] f = new int[n][50][50];
        for(int i = 0; i < n; ++i){
            int[][] d = f[i];
            for(int j = 0; j < 50; ++j){
                Arrays.fill(d[j], -1);
            }
            int px = positions[i][0], py = positions[i][1];
            d[px][py] = 0;
            List<int[]> q = List.of(new int[]{px, py});
            int step = 1;
            while(!q.isEmpty()){
                List<int[]> tmp = q;
                q = new ArrayList<>();
                for(int[] p : tmp){
                    for(int[] dir : dirs){
                        int x = p[0] + dir[0], y = p[1] + dir[1];
                        if(x >= 0 && x < 50 && y >= 0 && y < 50 && d[x][y] < 0){
                            d[x][y] = step;
                            q.add(new int[]{x, y});
                        }
                    }
                }
                ++step;
            }
        }
        int[][] memo = new int[n + 1][1 << n];
        for(int[] row : memo){
            Arrays.fill(row, -1);
        }
        return dfs(n, (1 << n) - 1, kx, ky, positions, f, memo);
    }
    private int dfs(int i, int mask, int kx, int ky, int[][] positions, int[][][] dis, int[][] memo) {
        if(mask == 0) return 0;
        if(memo[i][mask] != -1)return memo[i][mask];
        int n = positions.length;
        int x = i < n ? positions[i][0] : kx, y = i < n ? positions[i][1] : ky;
        int res = 0, u = (1 << n) - 1;
        if (Integer.bitCount(u ^ mask) % 2 == 0) {
            for (int j = 0; j < n; j++) {
                if ((mask >> j & 1) > 0) {
                    res = Math.max(res, dfs(j, mask ^ (1 << j), kx, ky, positions, dis, memo) + dis[j][x][y]);
                }
            }
        } else {
            res = Integer.MAX_VALUE;
            for (int j = 0; j < n; j++) {
                if ((mask >> j & 1) > 0) {
                    res = Math.min(res, dfs(j, mask ^ (1 << j), kx, ky, positions, dis, memo) + dis[j][x][y]);
                }
            }
        }
        return memo[i][mask] = res;
    }
}

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

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

相关文章

探索未来住宿新体验:酒店智能开关引领的智慧生活

酒店智能开关作为智慧酒店的重要组成部分&#xff0c;正悄然改变着我们的旅行住宿方式&#xff0c;让每一次入住都成为一场科技与舒适的完美邂逅。 智能开关&#xff1a;重新定义酒店房间的每一个角落 传统酒店中&#xff0c;房间的灯光、空调、窗帘等设备的控制往往依赖于手动…

LCD字符图片显示——FPGA学习笔记11

一、字模显示原理 字模数据&#xff1a;将这个0/1矩阵按照屏幕扫描的顺序以字节的形式体现。 取模软件设计&#xff1a; 点阵数要按照实际情况填写 二、实验任务 本节的实验任务是通过开发板上的RGB TFT-LCD接口&#xff0c;在RGB LCD液晶屏的左上角位置从上到下依次显示图片以…

【数据结构】希尔排序(缩小增量排序)

目录 一、基本思想 1.1 引入希尔排序的原因 1.2 基本思想 二、思路分析 三、gap分组问题 四、代码实现 4.1 代码一&#xff08;升序&#xff09; 4.2 代码二&#xff08;升序&#xff09; 五、易错提醒 六、时间复杂度分析 七、排序小tips 一、基本思想 1.1 引入希尔…

Vue3:<Teleport>传送门组件的使用和注意事项

你好&#xff0c;我是沐爸&#xff0c;欢迎点赞、收藏、评论和关注。 Vue3 引入了一个新的内置组件 <Teleport>&#xff0c;它允许你将子组件树渲染到 DOM 中的另一个位置&#xff0c;而不是在父组件的模板中直接渲染。这对于需要跳出当前组件的 DOM 层级结构进行渲染的…

15.1 JDBC数据库编程1

目录 15 引言 15.1.1 数据库语言SQL 15.2 JDBC体系结构 15.2.1 JDBC访问数据库 15.2.2 JDBC API介绍 15 引言 数据库系统&#xff08;database system,DBS&#xff09;由一个互相关联的数据集合和一组用以访问这些数据的程序组成。这个数据集合通常称为数据库。 …

音频-语言大模型原理

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

YOLOv8改进实战 | 注意力篇 | CloFormer: 注意力机制与卷积的完美融合CloAtention,即插即用

YOLOv8专栏导航:点击此处跳转 前言 YOLOv8 是由 YOLOv5 的发布者 Ultralytics 发布的最新版本的 YOLO。它可用于对象检测、分割、分类任务以及大型数据集的学习,并且可以在包括 CPU 和 GPU 在内的各种硬件上执行。 YOLOv8 是一种尖端的、最先进的 (SOTA) 模型,它建立在以前…

(C++) 6大作用域

文章目录 &#x1f365;前言&#x1f365;C 6大作用域&#x1f41f;块&#x1f41f;名字空间&#x1f41f;类&#x1f41f;函数参数&#x1f41f;枚举&#x1f41f;模板参数 ⭐END&#x1f31f;交流方式 &#x1f365;前言 在 C core guidelines 中有一个准则&#xff1a; ES.…

深入探索Unity协程:揭开CSharp迭代器背后的神秘面纱

协程是一种特殊类型的迭代器方法&#xff0c;允许你在多个帧之间分段执行代码。可以用来处理时间延迟、异步操作和顺序执行的任务&#xff0c;而不阻塞主线程。Unity协程的实现依赖于C#语言提供的迭代器相关的语言特性&#xff0c;所以想要弄清楚Unity协程的底层原理&#xff0…

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配&#xff08;Exact Match&#xff09;2. 正则表达式匹配&#xff08;Regex Match&#xff09;3. 前缀匹配&#xff08;Prefix Match&#xff09; 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中&#xff0…

Idea Mac代码调试常用快捷键~

Mac截图 commandShift4 idea英文大写转小写 commandShiftU 功能&#xff1a;查看类的实现和继承父类的方法 快捷键 fncommandF12 鼠标点击打开 功能&#xff1a;查看当前方法的上游方法 选中方法&#xff0c;controloptionH 功能&#xff1a;CommandB是查看本类的方法 功能&…

Matlab simulink建模与仿真 第十一章(端口及子系统库)【下】

参考视频&#xff1a;simulink1.1simulink简介_哔哩哔哩_bilibili 八、触发使能子系统 1、Enabled and Triggered Subsystem触发使能子系统概述 触发使能子系统其实是触发子系统和使能子系统二者的结合&#xff0c;当触发端口传来触发信号时&#xff0c;使能端口的输入需要大…

TitleBar:打造高效Android标题栏的新选择

在Android应用开发中&#xff0c;标题栏是用户界面的重要组成部分。一个好的标题栏不仅能够提升应用的专业感&#xff0c;还能增强用户体验。然而&#xff0c;传统的标题栏实现方式往往存在代码冗余、样式不统一、性能开销大等问题。今天&#xff0c;我们将介绍一个名为TitleBa…

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐&#xff1f; 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识&#xff0c;并举出了两个例子&#xff0c;我们再举出两个例子继续说明&…

python进阶篇-day08-数据结构与算法(线性结构介绍与链表实现)

数据的存储和组织形式 程序 数据结构 算法 一. 算法介绍 概述目的 都是可以提高程序的效率(性能), 面试高频考点 数据结构介绍 数据的存储和组织形式, 同样的空间, 不同的结构, 存储的数据不同, 操作方式也不同 算法介绍 为了解决实际的业务问题, 而考虑出来的方法和思路 …

龙芯+FreeRTOS+LVGL实战笔记(新)——06添加二级按钮

本专栏是笔者另一个专栏《龙芯+RT-Thread+LVGL实战笔记》的姊妹篇,主要的区别在于实时操作系统的不同,章节的安排和任务的推进保持一致,并对源码做了完善与优化,各位可以先到本人主页下去浏览另一专栏的博客列表(目前已撰写36篇,图1所示),再决定是否订阅。此外,也可以…

超强的截图工具:PixPin

你是否还在为寻找一款功能强大、操作简便的截图工具而烦恼&#xff1f;市面上那么多工具&#xff0c;常常让人无从选择。今天&#xff0c;想给大家安利一款神器——PixPin&#xff0c;一款真正解放双手的截图工具。 想象一下&#xff0c;你只需要按下快捷键就能轻松完成多种截…

雷电9模拟器安装magisk和lsposed

模拟器环境配置 1、开启root 2、开启System.vmdk可写入 安装magisk 1、新建模拟器、开启root权限、并安装debug版magisk 下载地址去上面吾爱论坛作者文章下载吧&#xff01;支持他一下&#xff01; 2、打开magisk的app&#xff0c;点击安装 如果弹出获取权限&#xff0c;直接…

【Socket网络编程原理实践】

socket 基于 TCP/IP协议实现&#xff0c;在网络模型中属于传输层 Java 网络编程中的核心概念 IP 地址&#xff1a;用于标识网络中的计算机端口号&#xff1a;用于标识计算机上的应用程序或进程Socket&#xff08;套接字&#xff09;&#xff1a;网络通信的基本单位&#xff0…

冒泡排序算法介绍

冒泡排序算法介绍 如果真的累了&#xff0c;就拉上窗帘关上手机关掉闹钟深呼吸一口气钻进被窝&#xff0c;好好地睡一觉&#xff0c;难熬的日子总需要一些温暖&#xff0c;而什么都不如被窝的温暖来的踏实。 冒泡排序是一种经典的排序算法&#xff0c;它通过重复遍历待排序的序…