周赛343(模拟、网格图求最短路、贪心)

news2024/12/24 9:00:36

文章目录

  • 周赛343
    • [6341. 保龄球游戏的获胜者](https://leetcode.cn/problems/determine-the-winner-of-a-bowling-game/)
      • 模拟 + 技巧
    • [2661. 找出叠涂元素](https://leetcode.cn/problems/first-completely-painted-row-or-column/)
      • 模拟
    • [2662. 前往目标的最小代价](https://leetcode.cn/problems/minimum-cost-of-a-path-with-special-roads/)
      • 网格图版求最短路径问题
    • [2663. 字典序最小的美丽字符串](https://leetcode.cn/problems/lexicographically-smallest-beautiful-string/)
      • 贪心

周赛343

6341. 保龄球游戏的获胜者

难度简单2

给你两个下标从 0 开始的整数数组 player1player2 ,分别表示玩家 1 和玩家 2 击中的瓶数。

保龄球比赛由 n 轮组成,每轮的瓶数恰好为 10

假设玩家在第 i 轮中击中 xi 个瓶子。玩家第 i 轮的价值为:

  • 如果玩家在前两轮中击中了 10 个瓶子,则为 2xi
  • 否则,为 xi

玩家的得分是其 n 轮价值的总和。

返回

  • 如果玩家 1 的得分高于玩家 2 的得分,则为 1
  • 如果玩家 2 的得分高于玩家 1 的得分,则为 2
  • 如果平局,则为 0

示例 1:

输入:player1 = [4,10,7,9], player2 = [6,5,2,3]
输出:1
解释:player1 的得分是 4 + 10 + 2*7 + 2*9 = 46 。
player2 的得分是 6 + 5 + 2 + 3 = 16 。
player1 的得分高于 player2 的得分,所以 play1 在比赛中获胜,答案为 1 。

示例 2:

输入:player1 = [3,5,7,6], player2 = [8,10,10,2]
输出:2
解释:player1 的得分是 3 + 5 + 7 + 6 = 21 。
player2 的得分是 8 + 10 + 2*10 + 2*2 = 42 。
player2 的得分高于 player1 的得分,所以 play2 在比赛中获胜,答案为 2 。

示例 3:

输入:player1 = [2,3], player2 = [4,1]
输出:0
解释:player1 的得分是 2 + 3 = 5 。
player2 的得分是 4 + 1 = 5 。
player1 的得分等于 player2 的得分,所以这一场比赛平局,答案为 0 。

提示:

  • n == player1.length == player2.length
  • 1 <= n <= 1000
  • 0 <= player1[i], player2[i] <= 10

模拟 + 技巧

题解:翻译有问题

  • 只要发现有一个10后面两个数字进行翻倍就好了。
class Solution:
    def isWinner(self, player1: List[int], player2: List[int]) -> int:
        def calc(sz: List[int]) -> int:
            n = len(sz)
            k = [1] * (n+2) # 统一处理最后两个元素
            for i in range(n):
                if sz[i] == 10:
                    k[i+1] = 2
                    k[i+2] = 2
            # 标记需要翻倍的得分,然后相加
            ans = 0
            for i in range(n):
                ans += sz[i] * k[i]
            return ans
        sum1 = calc(player1)
        sum2 = calc(player2)
        if sum1 == sum2:
            return 0
        elif sum1 > sum2:
            return 1
        else:
            return 2 

或者不先预处理,使用dp的思想,遍历i时,查看i-1和i-2位置是否为10

class Solution:
    def isWinner(self, player1: List[int], player2: List[int]) -> int:
        def calc(sz: List[int]) -> int:
            n = len(sz)
            ans = 0
            for i, x in enumerate(sz):
                if i and sz[i-1] == 10 or i > 1 and sz[i-2] == 10:
                    x *= 2
                ans += x
            return ans
        sum1 = calc(player1)
        sum2 = calc(player2)
        if sum1 == sum2:
            return 0
        elif sum1 > sum2:
            return 1
        else:
            return 2

2661. 找出叠涂元素

难度中等5

给你一个下标从 0 开始的整数数组 arr 和一个 m x n 的整数 矩阵 matarrmat 都包含范围 [1,m * n] 内的 所有 整数。

从下标 0 开始遍历 arr 中的每个下标 i ,并将包含整数 arr[i]mat 单元格涂色。

请你找出 arr 中在 mat 的某一行或某一列上都被涂色且下标最小的元素,并返回其下标 i

示例 1:

image explanation for example 1

输入:arr = [1,3,4,2], mat = [[1,4],[2,3]]
输出:2
解释:遍历如上图所示,arr[2] 在矩阵中的第一行或第二列上都被涂色。

示例 2:

image explanation for example 2

输入:arr = [2,8,7,4,1,3,5,6,9], mat = [[3,2,5],[1,4,6],[8,7,9]]
输出:3
解释:遍历如上图所示,arr[3] 在矩阵中的第二列上都被涂色。

提示:

  • m == mat.length
  • n = mat[i].length
  • arr.length == m * n
  • 1 <= m, n <= 105
  • 1 <= m * n <= 105
  • 1 <= arr[i], mat[r][c] <= m * n
  • arr 中的所有整数 互不相同
  • mat 中的所有整数 互不相同

模拟

1wa:注意行列关系,当某行出现次数达到列值时,说明这一行都出现过了

class Solution {
    public int firstCompleteIndex(int[] arr, int[][] mat) {
        Map<Integer, Integer> map = new HashMap<>();
        int m = mat.length, n = mat[0].length;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                map.put(mat[i][j], i * n + j);
            }
        }
        int[] row = new int[m];
        int[] col = new int[n];
        for(int i = 0; i < arr.length; i++){
            int pos = map.get(arr[i]);
            // arr[i] 在原数组的(x, y)位置
            int x = pos / n, y = pos % n;
            row[x]++; // 行和列对应位置 + 1
            col[y]++;
            // 某行或者某列计数满了,说明这一行/列都出现过了
            if(row[x] == n || col[y] == m) return i;
        }
        return -1;
    }
}

python

class Solution:
    def firstCompleteIndex(self, arr: List[int], mat: List[List[int]]) -> int:
        m, n = len(mat), len(mat[0])
        pos = [0] * (m*n + 1)
        for i, row in enumerate(mat):
            for j, x in enumerate(row):
                pos[x] = (i, j)
        row = [0] * m
        col = [0] * n
        for i, x in enumerate(arr):
            x, y = pos[x]
            row[x] += 1
            col[y] += 1
            if row[x] == n or col[y] == m:
                return i
        return -1

2662. 前往目标的最小代价

难度中等10

给你一个数组 start ,其中 start = [startX, startY] 表示你的初始位置位于二维空间上的 (startX, startY) 。另给你一个数组 target ,其中 target = [targetX, targetY] 表示你的目标位置 (targetX, targetY)

从位置 (x1, y1) 到空间中任一其他位置 (x2, y2) 的代价是 |x2 - x1| + |y2 - y1|

给你一个二维数组 specialRoads ,表示空间中存在的一些特殊路径。其中 specialRoads[i] = [x1i, y1i, x2i, y2i, costi] 表示第 i 条特殊路径可以从 (x1i, y1i)(x2i, y2i) ,但成本等于 costi 。你可以使用每条特殊路径任意次数。

返回从 (startX, startY)(targetX, targetY) 所需的最小代价。

示例 1:

输入:start = [1,1], target = [4,5], specialRoads = [[1,2,3,3,2],[3,4,4,5,1]]
输出:5
解释:从 (1,1) 到 (4,5) 的最优路径如下:
- (1,1) -> (1,2) ,移动的代价是 |1 - 1| + |2 - 1| = 1 。
- (1,2) -> (3,3) ,移动使用第一条特殊路径,代价是 2 。
- (3,3) -> (3,4) ,移动的代价是 |3 - 3| + |4 - 3| = 1.
- (3,4) -> (4,5) ,移动使用第二条特殊路径,代价是 1 。
总代价是 1 + 2 + 1 + 1 = 5 。
可以证明无法以小于 5 的代价完成从 (1,1) 到 (4,5) 。

示例 2:

输入:start = [3,2], target = [5,7], specialRoads = [[3,2,3,4,4],[3,3,5,5,5],[3,4,5,6,6]]
输出:7
解释:最优路径是不使用任何特殊路径,直接以 |5 - 3| + |7 - 2| = 7 的代价从初始位置到达目标位置。

提示:

  • start.length == target.length == 2
  • 1 <= startX <= targetX <= 105
  • 1 <= startY <= targetY <= 105
  • 1 <= specialRoads.length <= 200
  • specialRoads[i].length == 5
  • startX <= x1i, x2i <= targetX
  • startY <= y1i, y2i <= targetY
  • 1 <= costi <= 105

网格图版求最短路径问题

题解:https://leetcode.cn/problems/minimum-cost-of-a-path-with-special-roads/solution/zhi-jie-qiu-zui-duan-lu-wu-xu-jian-tu-by-i8h7/

怎么想到的Dijkstra求解问题?

题目求的是源点到终点的最小代价,是最短路问题,由于每条路径长度不相同,因此不能用BFS,退而求其次使用Dijkstra

Dijkstra:每次选择一条最小代价的边,拿这一条边去更新别的边的最小代价

class Solution:
    """
    起点固定的单源最短路问题 ==> Dijkstra
        当不走特殊路径时,答案=起点到终点点的曼哈顿距离
        当走特殊路径时,答案时起点到特殊路径起点 + cost 走到特殊路路径终点
    
    抽象成一个图,一共有n + 2个点
    ==> 稠密图直接 O(n^2)遍历
    
    """
    def minimumCost(self, start: List[int], target: List[int], specialRoads: List[List[int]]) -> int:
        t = tuple(target) # pair
        dis = defaultdict(lambda: inf)
        dis[tuple(start)] = 0 # 起点为距离为0
        vis = set() 
        while True:
            v = None
            # 遍历所有最短路上的点
            for p, d in dis.items():
                # 如果这个点没有vis过 并且 这个点的距离是最小的
                if p not in vis and (v is None or d < dis[v]):
                    v = p
            if v == t: # 如果当前最小的点是终点,直接返回
                return dis[v]
            vis.add(v)
            vx, vy = v # 提出横坐标和纵坐标
            # 更新到终点的最短路(直接走曼哈顿距离)
            dis[t] = min(dis[t], dis[v] + abs(t[0] - vx) + abs(t[1] - vy)) 
                
            for x1, y1, x2, y2, cost in specialRoads: # 遍历所有特殊路径
                w = (x2, y2)
                # 走法1 :(vx, vy) -> (x1, y1) -> 走特殊路径 -> (x2, y2) 
                #        abs(x1 -vx) + abs(y1 - vy) + cost
                # 走法2 :(vx, vy) -> (x2, y2) 直接走到终点  
                #        abs(x2 - vx) + abs(y2 - vy)
                # 选择更小的走法
                d = dis[v] + min(abs(x2 - vx) + abs(y2 - vy), abs(x1 -vx) + abs(y1 - vy) + cost)
                dis[w] = min(dis[w], d)

java

class Solution {
    public int minimumCost(int[] start, int[] target, int[][] specialRoads) {
        long t = (long) target[0] << 32 | target[1];
        var dis = new HashMap<Long, Integer>();
        dis.put(t, Integer.MAX_VALUE);
        dis.put((long) start[0] << 32 | start[1], 0);
        var vis = new HashSet<Long>();
        for (;;) {
            long v = -1;
            int dv = -1;
            for (var e : dis.entrySet())
                if (!vis.contains(e.getKey()) && (dv < 0 || e.getValue() < dv)) {
                    v = e.getKey();
                    dv = e.getValue();                
                }
            if (v == t) return dv; // 到终点的最短路已确定
            vis.add(v);
            int vx = (int) (v >> 32), vy = (int) (v & Integer.MAX_VALUE);
            // 更新到终点的最短路
            dis.merge(t, dv + target[0] - vx + target[1] - vy, Math::min);
            for (var r : specialRoads) {
                int d = dv + Math.abs(r[0] - vx) + Math.abs(r[1] - vy) + r[4];
                long w = (long) r[2] << 32 | r[3];
                if (d < dis.getOrDefault(w, Integer.MAX_VALUE))
                    dis.put(w, d);
            }
        }
    }
}

2663. 字典序最小的美丽字符串

难度困难4

如果一个字符串满足以下条件,则称其为 美丽字符串

  • 它由英语小写字母表的前 k 个字母组成。
  • 它不包含任何长度为 2 或更长的回文子字符串。

给你一个长度为 n 的美丽字符串 s 和一个正整数 k

请你找出并返回一个长度为 n 的美丽字符串,该字符串还满足:在字典序大于 s 的所有美丽字符串中字典序最小。如果不存在这样的字符串,则返回一个空字符串。

对于长度相同的两个字符串 ab ,如果字符串 a 在与字符串 b 不同的第一个位置上的字符字典序更大,则字符串 a 的字典序大于字符串 b

  • 例如,"abcd" 的字典序比 "abcc" 更大,因为在不同的第一个位置(第四个字符)上 d 的字典序大于 c

示例 1:

输入:s = "abcz", k = 26
输出:"abda"
解释:字符串 "abda" 既是美丽字符串,又满足字典序大于 "abcz" 。
可以证明不存在字符串同时满足字典序大于 "abcz"、美丽字符串、字典序小于 "abda" 这三个条件。

示例 2:

输入:s = "dc", k = 4
输出:""
解释:可以证明,不存在既是美丽字符串,又字典序大于 "dc" 的字符串。

提示:

  • 1 <= n == s.length <= 105
  • 4 <= k <= 26
  • s 是一个美丽字符串

贪心

题解:https://leetcode.cn/problems/lexicographically-smallest-beautiful-string/solution/tan-xin-pythonjavacgo-by-endlesscheng-yix5/

class Solution:
    """
    它不包含任何长度为 2 或更长的回文子字符串。
    
    长度为6的回文串一定包含长度为4 为2的回文串
    贪心:只要保证不存在长度为2的回文串就不会有更长的回文串

    从右到左修改
    用进位的概念,把字符串看成一个k进制数
    """
    def smallestBeautifulString(self, s: str, k: int) -> str:
        a = ord('a')
        k += a
        s = list(map(ord, s))
        n = len(s)
        i = n - 1
        s[i] += 1  # 从最后一个字母开始
        while i < n:
            if s[i] == k:  # 超过范围
                if i == 0: return ""  # 无法进位
                # 进位
                s[i] = a
                i -= 1 # 有限解决前面的回文串
                s[i] += 1
            # 讨论长为 2 和长为 3 的回文串的情况,继续累加
            elif i and s[i] == s[i - 1] or i > 1 and s[i] == s[i - 2]:
                s[i] += 1  # 如果 s[i] 和前面的字符形成回文串,就继续增加 s[i]
            else:
                i += 1  # 检查 s[i] 是否和后面的字符形成回文串
        return ''.join(map(chr, s))

“” # 无法进位
# 进位
s[i] = a
i -= 1 # 有限解决前面的回文串
s[i] += 1
# 讨论长为 2 和长为 3 的回文串的情况,继续累加
elif i and s[i] == s[i - 1] or i > 1 and s[i] == s[i - 2]:
s[i] += 1 # 如果 s[i] 和前面的字符形成回文串,就继续增加 s[i]
else:
i += 1 # 检查 s[i] 是否和后面的字符形成回文串
return ‘’.join(map(chr, s))


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

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

相关文章

给jar包编写start和stop脚本

文章目录 前言一、编写脚本1.start.sh2.stop.sh3.restart.sh 二、展示总结 前言 springboot项目内置tomcat,一般都是以jar包形式对外发布服务,我们不能每次都去kill pid,抽到脚本里来做这个事会方便许多。 一、编写脚本 1.start.sh #!/bin/bash APP_NAME"springboot2.3…

基于深度学习的水果检测与识别系统(Python界面版,YOLOv5实现)

摘要&#xff1a;本博文介绍了一种基于深度学习的水果检测与识别系统&#xff0c;使用YOLOv5算法对常见水果进行检测和识别&#xff0c;实现对图片、视频和实时视频中的水果进行准确识别。博文详细阐述了算法原理&#xff0c;同时提供Python实现代码、训练数据集&#xff0c;以…

QT 中的多线程之 moveToThread

文章目录 1. 概述2. 方法描述3. 代码&#xff1a;4. 运行结果及说明5. 注意事项6. 结语 1. 概述 ​QThread 类提供了一个与平台无关的管理线程的方法。一个 QThread 对象管理一个线程。 QThread 的执行从 run() 函数的执行开始&#xff0c;在 Qt 自带的 QThread 类中&#xf…

GraalVM编译SpringBoot程序

GraalVM 提供了一个名为 “Native Image” 的工具&#xff0c;它能够将 Java 应用程序预编译成本机可执行文件。这种方法的优点是启动速度快&#xff0c;内存占用少&#xff0c;因为程序运行时不需要 JVM 和类加载。 然而这种方式也存在一些弊端&#xff0c;如预编译的 GraalV…

扩展ACL配置

扩展ACL配置 【实验目的】 掌握扩展ACL的配置。认识扩展ACL的作用。验证配置。 【实验拓扑】 实验拓扑如图1所示。 图1 实验拓扑 设备参数如表所示。 表1 设备参数表 设备 接口 IP地址 子网掩码 默认网关 R1 S0/3/0 192.168.1.1 255.255.255.252 N/A Fa0/0/0 …

操作系统:文件系统基础

文件系统基础 ​ 文件是以硬盘为载体的存储在计算机上的信息集合&#xff0c;文件可以是文档、图片、程序等。在系统运行时&#xff0c;计算机以进程为基本单位进行资源的调度和分配&#xff1b;而在用户的输入和输出中&#xff0c;则以文件为基本单位 文件控制块和索引节点 …

【Python基础练习100题--第二篇:文件篇】

前言 这些题都是在B站的练习题&#xff0c;链接在这 对于刚学python的新手来说十分的适合&#xff0c; 可以加强和巩固我们的基础。 嘿嘿 一起噶油吧&#xff01;&#x1f349; &#x1f349;1.对学生成绩排序 # 这里对字典进行排序&#xff0c;同事使用到了sorted函数 # 这…

stm32F103 WIFIESP8266模块连接阿里云平台

(43条消息) ESP8266 AT MQTT 透传指令接入阿里云物联网平台笔记&#xff1b;_安信可科技的博客-CSDN博客 这里这篇博客提到的固件是错误的 我用的固件是这个&#xff0c;刷固件之后&#xff0c;可以连上阿里云。 ATMQTTCLIENTID0,"ClienId"//clientId第二个参数注…

权限提升:烂土豆 || DLL 劫持.

权限提升&#xff1a;烂土豆 || DLL 劫持. 权限提升简称提权&#xff0c;由于操作系统都是多用户操作系统&#xff0c;用户之间都有权限控制&#xff0c;比如通过 Web 漏洞拿到的是 Web 进程的权限&#xff0c;往往 Web 服务都是以一个权限很低的账号启动的&#xff0c;因此通…

数字化转型:如何利用文件管理系统提高制造业的工作效率

对于制造行业的企业用户&#xff0c;在日常企业文件管理中会遇到怎样的问题呢&#xff1f;制造业又该该如何高效管理文件呢&#xff1f; 这些问题困扰着机械制造行业客户…… 1&#xff09;项目多、文件杂&#xff0c;统一管理不便 2&#xff09;文档资料在公司内部流转不畅 …

14-5-进程间通信-信号

一、信号的基本概述 1.什么是信号&#xff1f; &#xff08;1&#xff09;对于linux来说&#xff0c;信号是软中断。比如在终端输入ctrlc来中断正在运行的程序&#xff0c;原理是linux通过信号机制来停止一个程序。 &#xff08;2&#xff09;每一个信号都有一个名字和编号&…

Django项目页面样式如何“传给”客户端浏览器

前言 django项目在视图函数中借助render函数可以返回HTML页面&#xff0c;但是HTML页面中如果引入了外部CSS文件或者JavaScript文件在浏览器页面无法加载&#xff0c;因此就必须有一种方式能够将HTML文档中引入的外部文件能够在客户端浏览器上加载&#xff0c;这种方式就是配置…

QML状态与过渡(States and Transitions)

目录 一 状态&#xff08;States&#xff09; 一 过渡&#xff08;Transitions&#xff09; 通常我们将用户界面描述为一种状态。一个状态定义了一组属性的改变&#xff0c;并且会在一定的条件下被触发。另外在这些状态转化的过程中可以有一个过渡&#xff0c;定义了这些属性…

第二十章 中介者模式

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

SpringSecurity框架学习与使用

SpringSecurity框架学习与使用 SpringSecurity学习SpringSecurity入门SpringSecurity深入认证授权自定义授权失败页面权限注解SecuredPreAuthorizePostAuthorizePostFilterPreFilter 参考 SpringSecurity学习 SpringSecurity入门 引入相关的依赖&#xff0c;SpringBoot的版本…

IPsec中IKE与ISAKMP过程分析(快速模式-消息3)

IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息1&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息2&#xff09;_搞搞搞高傲的博客-CSDN博客 IPsec中IKE与ISAKMP过程分析&#xff08;主模式-消息3&#xff09;_搞搞搞高傲的博客…

Spring - IoC

Spring - IoC Spring- IoC1)Spring简介1.1)什么是框架1.2)框架的作用1.3)Spring是什么1.4)Spring的体系结构1.5)Spring的发展历史1.6)Spring优势 2)IoC简介2.1)优质程序代码的制作原则2.2)耦合与内聚2.3)工厂模式发展史2.4)Spring发展历程2.5)IoC 3)入门案例3.1)案例环境说明3.…

synchronized用法加锁原理

目录 使用场景不同场景加锁对象结论验证实验实验1&#xff1a; synchronized 修饰方法&#xff0c;加锁对象是类实例&#xff0c;不同实例之间的锁互不影响实验2&#xff1a; synchronized 加在静态方法上&#xff0c;加锁对象是方法所在类&#xff0c;不同类实例之间相互影响实…

docker镜像导入导出

项目背景 1. docker pull 的时候比较慢的情况下&#xff0c; 之前已经下载过的话&#xff0c;可以直接导入使用 2. 有些服务器不允许上外网的情况下&#xff0c;可以先在自己电脑上下载好&#xff0c;再上传到服务器上进行安装 导出镜像 查看镜像 docker images 导出镜像 …