几道洛谷Python答案解析(入门做)

1 篇文章 0 订阅
1 篇文章 0 订阅

网址: 题目列表 - 洛谷

推荐博主:https://github.com/happy-join-github/-_-

代码来源:只能靠自己或和GPT了……因为看了洛谷用户规则,评论区的题解是不能转发的。

目录

1000

复杂度

1001

算法竞赛中要求的输出格式中,不能有多余的内容。

map

1002

生成器表达式

all()

嵌套的列表推导式

动态规划

1035

Python类型提示

1047

1046


1000
print("""                ********
               ************
               ####....#.
             #..###.....##....
             ###.......######              ###            ###
                ...........               #...#          #...#
               ##*#######                 #.#.#          #.#.#
            ####*******######             #.#.#          #.#.#
           ...#***.****.*###....          #...#          #...#
           ....**********##.....           ###            ###
           ....****    *****....
             ####        ####
           ######        ######
##############################################################
#...#......#.##...#......#.##...#......#.##------------------#
###########################################------------------#
#..#....#....##..#....#....##..#....#....#####################
##########################################    #----------#
#.....#......##.....#......##.....#......#    #----------#
##########################################    #----------#
#.#..#....#..##.#..#....#..##.#..#....#..#    #----------#
##########################################    ############""")
复杂度

注意:问了上面的这位博主,原来竞赛们的那个范围不是用if写出来的,只是表示复杂度用的呀!

1001

算法竞赛中要求的输出格式中,不能有多余的内容。

这也包括了“请输入整数 a 和 b” 这一类的提示用户输入信息的内容。若包含了这些内容,将会被认为是 Wrong Answer,即洛谷上的 WA。在对比代码输出和标准输出时,系统将忽略每一行结尾的空格,以及最后一行之后多余的换行符。

若因此类问题出现本机(看起来)AC,提交 WA 的现象,请勿认为是洛谷评测机出了问题,而是你的代码中可能存在多余的输出信息。用户可以参考在题目末尾提供的代码。

注意:
Pascal 使用 integer 会爆掉哦!
有负数哦!
C/C++ 的 main 函数必须是 int 类型,而且 C 最后要 return 0。这不仅对洛谷其他题目有效,而且也是 NOIP/CSP/NOI 比赛的要求!

map

map将一个函数应用到一个或多个可迭代对象的所有元素上,然后返回一个 map 对象。

map(function, iterable, ...)

map(函数,可迭代对象)

function是一个函数,它将被应用到每个可迭代对象中的对应元素上。
iterable是一个或多个可迭代对象,它们的元素将作为参数传递给 `function`。

多个可迭代对象时,格式如:使用 map 函数将 add_numbers 函数应用到两组数字上
result = map(add_numbers, numbers1, numbers2)

 map(int, ...) 将 int 函数应用于这个列表中的每个元素,将其转换为整数。

最终结果是一个包含两个整数值的 map 对象,这两个值将被解包并分别赋给 a 和b。

a, b = map(int, input().split())
print(a + b)
1002
生成器表达式

生成器表达式是一种紧凑的方式来创建生成器对象。它类似于列表推导式,但使用圆括号而不是方括号。生成器表达式的基本格式如下:
generator_expression = (expression for item in iterable)

生成器 =(生成器要产生的值或表达式  for  迭代过程中的变量名  in在  可迭代对象)

在这里,expression是生成器要产生的值,iterable是可迭代对象,item 是迭代过程中的变量名。

下面是一个简单的示例,演示如何使用生成器表达式来生成一个简单的生成器:
# 生成器表达式示例
my_list = [1, 2, 3, 4, 5]
my_generator = (x * x for x in my_list)  # 生成一个平方的生成器

# 遍历生成器
for val in my_generator:
    print(val)

在这个示例中,`(x * x for x in my_list)` 就是一个生成器表达式,它会产生一个包含 my_list 中每个元素的平方的生成器。

all()

all 函数是 Python 中的一个内置函数,用于判断可迭代对象中的所有元素是否都为真。如果可迭代对象中的所有元素都为真值(非零、非空、非None等),all函数将返回 True;否则返回 `False`。
all(可迭代对象)

以下是一个简单的示例,演示了如何使用 `all` 函数:
#检查元组中的所有元素是否都为真
my_tuple = (10, 20, 30, 40)
print(all(my_tuple))  # 输出:True,因为所有元素都非零
在这个示例中,`all` 函数被用来检查不同类型的可迭代对象中的所有元素是否都为真。

嵌套的列表推导式

可以在内部的列表推导式中包含另一个列表推导式,以便生成二维数组或更复杂的数据结构。以下是嵌套的列表推导式的基本格式:
# 基本格式
[[expression for j in iterable_inner] for i in iterable_outer]

[[根据内层循环变量生成的值的表达式  for  j嵌套的循环变量  in在  内层可迭代对象]  for  i外层循环变量   in在  内层循环的可迭代对象]

# 或者可以带有条件
[[expression if condition else other_expression for j in iterable_inner] for i in iterable_outer]

[[根据内层循环变量生成的值的表达式  if  条件  else  等于其他表达式 for  j嵌套的循环变量  in在  内层可迭代对象]  for  i外层循环变量   in在  内层循环的可迭代对象]

其中:

expression是根据内层循环变量生成的值的表达式。
condition是一个表达式,用于根据特定条件决定生成的值。
other_expression 是当条件不满足时生成的值的表达式。
iterable_inner和 iterable_outer分别是内层和外层循环的可迭代对象。
- i 和 j 分别是内层和外层循环的变量。

嵌套的列表推导式可以应用于各种数据结构的生成,包括二维数组、嵌套列表、字典等。使用嵌套的列表推导式可以在一行内清晰地生成复杂的数据结构,提高代码的可读性。

动态规划

动态规划是一种通过将原问题分解为相对简单的子问题来求解复杂问题的方法。通常来说,动态规划问题可以使用以下步骤来解决:

1. 定义状态:首先,需要定义问题的状态。状态是原问题中会变化的量。这些状态可以是位置、剩余步数、剩余物品等。在动态规划中,通常会定义一个二维数组或者更高维的数组来表示状态。

2. 找到状态转移方程: 状态转移方程描述了状态之间的关系,即如何根据已知的状态得到新的状态。这是动态规划问题的核心部分。通过状态转移方程,可以将原问题分解为子问题,并找到子问题之间的联系。

3. 确定边界条件:边界条件指的是最简单的、不需要依赖其他状态即可求解的情况。在动态规划中,通常需要确定初始状态或者边界状态的值。

4. 编写代码实现:根据以上步骤找到的状态定义、状态转移方程和边界条件,编写代码来实现动态规划算法。

一般来说,动态规划问题的代码格式:
# 初始化状态定义
# 处理边界条件
# 循环填表或递归计算状态转移方程
# 返回结果

并不是所有的动态规划问题都能以相同的方式解决,有时可能需要使用不同的技巧和方法。但是上述步骤是解决动态规划问题时常见的一般性步骤。

# 定义函数,从用户输入中获取四个整数值,并确保它们都大于等于0,因为数组的索引从0开始,负数索引是无效的。
def get_input():
    # 无限循环的结构,它会一直重复执行其中的代码块,持续等待用户输入.。
    while True:
        input_values = input().split()  # 从用户输入中获取值并空格分割
        """检查确保输入被分割后包含了四个值,使用生成器表达式。
                它实际上遍历了`input_values`中的每个值,并检查这个值是否都是由数字组成的。
                isdigit() 方法用于判断字符串是否全为数字字符。
                如果所有的值都是由数字组成的,这个表达式的结果就是True。
        """
        if len(input_values) == 4 and all(val.isdigit() for val in input_values):
            zx, zy, mx, my = map(int, input_values)  # 定义变量,并将输入的字符串形式input转换为整数
            if zx >= 0 and zy >= 0 and mx >= 0 and my >= 0:  # 确保所有值都大于等于0
                return zx, zy, mx, my  # 返回输入的四个值
        input_values.strip()  # 去除两端空格


zx, zy, mx, my = get_input()  # 获取用户输入的四个值

# 初始化动态规划数组,大小为(zx+1) * (zy+1),并将起点位置初始化为1,其余位置初始化为0
arr = [[1 if i == 0 and j == 0 else 0 for j in range(zy + 1)] for i in range(zx + 1)]

# 定义马能否到达的函数
# 定义马能否到达目标位置的函数
"""
每个元组内的两个值分别代表了在横向和纵向上的相对坐标偏移量。
相对坐标是根据象棋中马的走法得出的。在象棋中,马可以沿着 "日" 字形移动,也就是横向或纵向移动两步,然后再移动一步,或者横向或纵向移动一步,然后再移动两步。这些相对坐标就是根据这种移动规则得出的,它们表示了马在当前位置的基础上可以移动到的所有可能位置。
"""
zb = {(-1, 2), (1, 2), (1, -2), (-1, -2), (-2, 1), (2, 1), (2, -1), (-2, -1)}  # 马能走的所有位置的相对坐标


def ma(x, y):
    if (x, y) == (mx, my):  # 如果当前位置是目标位置
        return True
    for wx, wy in zb:  # 遍历马能走的所有位置.使用了一个循环来遍历变量 zb中的所有元组,每个元组表示了马能够移动到的相对位置。
        if (x, y) == (mx + wx, my + wy):  # 如果当前位置能走到目标位置.判断在给定的棋盘上,马在当前位置 (x, y)是否能够移动到目标位置 (mx, my)。
            return True
    return False  # 否则不能到达目标位置


# 动态规划
# 通过两个嵌套的 for 循环遍历了整个棋盘,其中 zx 和 zy 分别是棋盘的横纵坐标的最大值。
for i in range(zx + 1):
    for j in range(zy + 1):
        if not ma(i, j):  # 在每次遍历中,使用 ma(i, j)函数来检查当前位置 (i, j) 是否可以到达目标位置。如果当前位置不能到达目标位置,就通过动态规划的思想计算从起点到达当前位置的路径总数。
            if i > 0:  # 如果当前位置向下移动一步仍在范围内(即 `j > 0`),那么将当前位置的路径总数加上从上边位置到达当前位置的路径总数 `arr[i][j-1]`。
                arr[i][j] += arr[i - 1][j]  # 向右移动的走法数目
            if j > 0:  # 如果在范围内
                arr[i][j] += arr[i][j - 1]  # 向下移动的走法数目

# 输出结果
print(arr[zx][zy])  # 打印出从起始位置到目标位置的走法数目

最后有典型的动态规划状态转移方程的实现,用于更新到达当前位置 `(i, j)` 的路径总数。

if i > 0和if j > 0这两代码分别检查当前位置向右和向下移动一步是否仍在棋盘范围内。

arr[i][j] += arr[i - 1][j]:如果当前位置向右移动一步仍在范围内,那么将当前位置的路径总数 `arr[i][j]` 增加上从左边位置到达当前位置的路径总数 `arr[i-1][j]`。这表示使用了从左边位置到达当前位置的路径总数来更新当前位置的路径总数。

arr[i][j] += arr[i][j - 1]:如果当前位置向下移动一步仍在范围内,那么将当前位置的路径总数 arr[i][j] 增加上从上边位置到达当前位置的路径总数 arr[i][j-1]。这表示使用了从上边位置到达当前位置的路径总数来更新当前位置的路径总数。

这些操作反映了动态规划中的状态转移过程,通过利用之前计算得到的结果来更新当前状态的值,从而逐步求解更复杂的问题。

1035
def find_min_n(k):
    n = 1  # 初始化 n 为 1
    s = 0  # 初始化部分和 s 为 0
    while s <= k:  # 当部分和小于等于 k 时执行循环
        s += 1 / n  # 将 1/n 加到部分和 s 上
        n += 1  # n 自增 1
    return n-1 # 返回 n-1,因为事先加了1


# 从标准输入中读取 k 的值
k = int(input())  # 从标准输入中读取 k 的值
min_n = find_min_n(k)  # 调用函数计算最小的 n
print(min_n)  # 输出结果

"""
当部分和 s 首次大于 k 时,实际上是在 n 的值为满足条件的最小值时。
但由于我们是先将 1/n 加到部分和 s 上,然后再将 n 加 1,
所以当 s 首次大于 k 时,n 的值会比实际所需的大 1。
因此,我们需要返回 n - 1 而不是 n。"""
Python类型提示

形如  

def sum_num(k:int)->int:

当在Python中看到类似`k: int`和`-> int`这样的语法时,这是Python的类型提示(Type Hints)的一部分。类型提示是在Python 3.5版本中引入的,它允许添加关于函数参数和返回值的类型信息,但这些类型提示本身并不会影响代码的实际执行。它们只是提供了额外的信息,以便于代码的阅读和理解,并且在某些情况下可以帮助代码分析工具检查代码的正确性。

下面是关于类型提示的详细介绍:

1. **参数类型提示**:在函数定义中,可以使用`参数名: 类型`的语法来声明参数的类型。例如:
   ```python
   def greet(name: str) -> None:
       print("Hello, " + name)
   ```
   在这个例子中,`name: str`表示`greet`函数接受一个字符串类型的参数`name`。

2. **返回值类型提示**:在函数定义的括号后面,可以使用`-> 类型`的语法来声明函数的返回类型。例如:
   ```python
   def add(a: int, b: int) -> int:
       return a + b
   ```
   在这个例子中,`-> int`表示`add`函数会返回一个整数类型的值。

3. **类型注解**:类型提示本身并不会影响代码的执行,它们只是提供了额外的信息。Python解释器在执行代码时会忽略这些类型提示。然而,类型提示可以被静态类型检查器(如mypy)等工具使用,这些工具可以帮助你找出代码中潜在的类型问题。

4. **可选类型**:类型提示是可选的,你可以选择是否在代码中使用类型提示。对于小型项目或者个人项目来说,你可以选择是否添加类型提示,但在大型项目或者多人协作的情况下,类型提示可以提供更多的文档和可读性。

总之,类型提示是Python中的一种可选特性,帮助更好地理解代码,并且在一些情况下可以提供额外的帮助来检查代码的正确性。

1047

代码定义了一个名为`clear_trees`的函数,它的作用是计算在清除特定区域的树木后剩余的树木数量。然后,它读取道路长度`l`和需要清除树木的区域数量`m`作为输入。每个需要清除树木的区域用一对表示起点和终点的列表来表示。

以下是代码的详细解释:

1. **函数 `clear_trees`**:
   - 函数`clear_trees`接受两个参数:`l`(道路长度)和`areas`(需要清除树木的区域的起点和终点组成的列表)。
   - 它初始化一个名为`road`的列表,用于表示带有树木的道路。列表中的每个元素代表道路上的一个位置,最初所有位置都被认为有树木(用`1`表示)。

   - 然后,它遍历需要清除的区域列表,并更新`road`列表,将指定起点和终点范围内的元素设置为`0`,表示这些区域内的树木已经被清除。

   - 最后,它通过求和`road`列表中的元素来计算剩余的树木数量。

2. **读取输入**:
   - 代码读取两个用空格分隔的整数`l`和`m`,分别表示道路长度和需要清除的区域数量。
   - 然后读取每个需要清除的区域的起点和终点。

3. **计算和输出**:
   - 使用输入参数调用函数`clear_trees`,并将结果存储在变量`result`中。
   - 然后打印剩余的树木数量(`result`)作为输出。

比如,给定输入:
```
10 2
2 5
7 8
```

这表示道路长度为10个单位,并且有两个需要清除的区域:从位置2到5和从位置7到8。函数将计算清除这些区域后剩余的树木数量,并将结果打印输出。
def clear_trees(l, areas):
    # 初始化道路上的树,全部为1,表示有树
    road = [1] * (l + 1)

    # 遍历需要清除的区域
    for start, end in areas:
        # 清除区域内的树木
        for i in range(start, end + 1):
            road[i] = 0

    # 统计剩余的树木数量
    remaining_trees = sum(road)
    return remaining_trees

# 读取输入
# 读取道路长度l和需要清除树木的区域数量m
l, m = map(int, input().split())
# 读取每个需要清除的区域的起点和终点
areas = [list(map(int, input().split())) for _ in range(m)]

# 计算剩余的树木数量并输出结果
result = clear_trees(l, areas)
print(result)
1046
# 从标准输入获取10个苹果到地面的高度,并将其转换为整数列表
apple_heights = list(map(int, input().split()))

# 从标准输入获取陶陶把手伸直的时候能够达到的最大高度
reach_height = int(input())

# 初始化一个变量来存储陶陶能够摘到的苹果数量
reachable_apples = 0

# 遍历每个苹果的高度
for height in apple_heights:
    # 如果苹果的高度小于等于(陶陶把手伸直的最大高度 + 30),则表示陶陶能够摘到这个苹果,计数器加1
    if height <= reach_height + 30:
        reachable_apples += 1

# 打印出能够摘到的苹果数量
print(reachable_apples)

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值