洛谷 官方题库 python 第五天

文章介绍了如何运用递归和递推思想解决编程问题,如计算斐波那契数列(涉及P1255爬楼梯和P1002过河卒)、处理外星密码(字符串解压)以及计算幂次方(P1010)。文章通过实例展示了这些概念在实际问题中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

递归和递推

P1255 数楼梯

N=int(input())
def climbStairs(n):
    if n == 1:
        return 1
    elif n == 2:
        return 2
    else:
        return climbStairs(n - 1) + climbStairs(n - 2)
print(climbStairs(N))

这里用到了

斐波那契数列是一个非常经典的数学问题,它是一个无限序列,起始于0和1,后续的每个数字都是前两个数字之和。因此,斐波那契数列的前几个数字是0, 1, 1, 2, 3, 5, 8, 13, 21, 34等等。

斐波那契数列常见的表达式是:

F(n)=F(n−1)+F(n−2)

其中 F(0)=0, F(1)=1。

假设我们要爬n阶楼梯,每次可以爬1阶或2阶。为了到达第n阶楼梯,我们可以从第n-1阶楼梯爬1阶上去,或者从第n-2阶楼梯爬2阶上去。因此,到达第n阶楼梯的方法数等于到达第n-1阶楼梯的方法数与到达第n-2阶楼梯的方法数之和。

这正好是斐波那契数列的递推关系。当楼梯阶数为1时,只有一种爬法(爬1阶),当楼梯阶数为2时,有两种爬法(爬1阶两次或者爬2阶一次)。而对于更高的阶数,就可以根据上述的递推关系依次计算出不同阶数的爬法数量,这就是为什么爬楼梯问题可以用斐波那契数列来解决的原因。

 P1002 [NOIP2002 普及组] 过河卒

P2437

n, m = map(int, input().split())  # 从标准输入中读取两个整数,分别赋值给变量 n 和 m

dp = ['0' for _ in range(m + 10)]  # 创建一个长度为 m+10 的列表 dp,并将其初始化为字符串 '0'

dp[n] = 1  # 将 dp 列表中的第 n 项设置为 1
dp[n + 1] = 1  # 将 dp 列表中的第 n+1 项设置为 1

for i in range(n + 2, m + 1):  # 从 n+2 开始迭代到 m,计算斐波那契数列的剩余项
    dp[i] = dp[i - 1] + dp[i - 2]  # 计算斐波那契数列的第 i 项,根据递推关系,即前两项的和

print(dp[m])  # 打印斐波那契数列的第 m 项的值

P1928 外星密码

string.rindex()是从右向左找

def unzip(s):
    s = s.strip('[]')  # 去掉字符串两端的方括号
    cout = 0  # 初始化计数器
    for t in s:  # 遍历字符串中的每个字符
        if t in [f'{i}' for i in range(10)]:  # 如果字符是数字0-9中的一个
            cout += 1  # 计数器加1
    temp = s[cout:]  # 将计数器之后的部分作为解压后的字符串
    n = int(s[:cout])  # 将计数器之前的部分转换为整数,表示重复次数
    return temp * n  # 返回解压后的字符串

s = input()  # 从标准输入读取字符串

while True:
    try:
        left = s.rindex('[')  # 从右向左找到最后一个左方括号的索引
        right = s.index(']', left)  # 在左方括号之后找到对应的右方括号的索引
    except:
        break  # 如果找不到左右方括号,则退出循环
    temp = s[left:right + 1]  # 获取此时的压缩片段,例如:'[2ef]'
    s = s.replace(temp, unzip(temp))  # 将压缩片段解压,并替换原字符串中的压缩片段

print(s)  # 打印解压后的字符串

有点没看懂

str.replace(old, new[, count]) 方法用于将字符串中的所有旧子字符串替换为新子字符串。它返回一个新的字符串,其中所有出现的旧子字符串都被替换为新子字符串。

  • old:需要被替换的子字符串。
  • new:用于替换的新子字符串。
  • count:可选参数,表示替换的最大次数。如果指定,则只替换前 count 次出现的旧子字符串。

例如:

s = "hello world" new_s = s.replace("world", "Python")

print(new_s) # 输出: hello Python

  1. if t in [f'{i}' for i in range(10)]:

    • 这行代码使用了列表推导式 [f'{i}' for i in range(10)],它生成了一个包含字符串形式的数字 0 到 9 的列表。例如,这个列表看起来像 ['0', '1', '2', ..., '9']
    • 因此,if t in [f'{i}' for i in range(10)]: 的意思是:如果变量 t 是字符串形式的数字 0 到 9 中的一个,条件就为真。
  2. if t in [i for i in range(10)]:

    • 这行代码使用了列表推导式 [i for i in range(10)],它生成了一个包含数字 0 到 9 的列表。例如,这个列表看起来像 [0, 1, 2, ..., 9]
    • 因此,if t in [i for i in range(10)]: 的意思是:如果变量 t 是数字 0 到 9 中的一个,条件就为真。

总的来说,这两行代码的作用是相同的,都是用来检查变量 t 是否在数字 0 到 9 中。只是一个用了字符串形式的数字,而另一个用了整数形式的数字。

P1010 [NOIP1998 普及组] 幂次方


##抄的大佬代码,不好懂
import math

def micifang(n):
    flag=False  # 判断是否输出‘+’
    while n!=0:
        i=int(math.log2(n))# 获取当前最大的幂次,如:log2(137) = 7.xxx, int()直接得到了7
        if flag:# 判断是否是第一个元素
            print("+",end="")
        if i==0:# 如果为n=2**1则不需要递归了直接输出
            print("2(0)",end="")
        elif i==1:# 如果n=1则不需要递归了直接输出
            print("2",end="")
        else: # 随后按照要求输出递归就行了
            print("2(",end="")
            micifang(i)
            print(")",end="")
        n=n-2**i# 更新n值
        flag=True
n=int(input())

micifang(n)###不用print,在执行时已经打印了

<think>好的,用户想找P5734问题的Python解题思路和代码实现。首先,我需要确认一下P5734的具体题目内容。根据题库,P5734的题目名称是【深基6.例6】文字处理软件。题目大意是模拟一个文字处理软件的操作,包括插入字符串、删除指定区间的字符、替换特定子串以及查找子串位置等功能。 接下来,我需要回忆或查找该题的具体要求。根据记忆,题目通常要求处理初始字符串,并根据输入的一系列操作指令执行相应的字符串操作。每个操作对应不同的功能,例如: 1. 插入操作:在指定位置插入字符串。 2. 删除操作:删除从指定位置开始的若干个字符。 3. 替换操作:将特定子串替换为另一个字符串。 4. 查找操作:返回子串的起始位置。 用户需要的是Python的实现方法,所以需要思考如何用Python的字符串操作或列表来处理这些功能。Python的字符串是不可变对象,因此频繁修改可能会影响效率,但对于题目给定的数据范围来说,直接操作应该是可行的。 首先,初始字符串的读取,然后处理多个操作指令。每个指令的第一个数字代表操作类型,后面跟着参数。例如,插入操作可能需要两个参数:位置和插入的字符串。删除操作需要起始位置和删除的字符数。替换和查找操作则需要相应的子串参数。 需要注意输入的格式,尤其是插入和替换操作中的字符串参数可能包含空格,需要正确处理输入的分隔。例如,在Python中,使用split()方法可能会将后续的字符串按空格分割,导致错误。因此,可能需要先按第一个空格分割操作类型和参数,再处理剩下的参数,特别是当参数中包含字符串时,需要将后面的部分作为完整的字符串处理。 举个例子,插入操作的指令可能是这样的格式:“1 position str”,其中position是插入的位置,str是要插入的字符串。这时候,如果直接用split(),会把str中的空格也分割开,导致错误。因此,正确的处理方法是先分割出操作类型,然后处理剩下的参数。例如,使用字符串的split(maxsplit=2)方法,限制分割次数。 接下来,针对每个操作类型: 1. 插入操作:将字符串插入到指定位置。例如,原字符串s,在位置pos后插入字符串a,可以分片处理为s[:pos+1] + a + s[pos+1:]。但需要注意Python中的字符串索引是从0开始的,而题目中的位置可能从1开始,或者要看具体题目描述。需要确认题目的位置定义。 2. 删除操作:删除从位置pos开始的连续len个字符。同样需要考虑索引的问题,比如题目中的位置是否从0或1开始,删除的长度是否可能超出字符串长度,这时候可能需要取最小值。 3. 替换操作:将所有的指定子串替换为目标子串。可以使用字符串的replace方法,但需要注意题目是否需要替换所有出现还是仅第一个出现。根据题目描述,如果是替换所有,则需要多次替换。 4. 查找操作:返回子串第一次出现的起始位置,如果没有则返回-1。可以使用字符串的find方法。 现在需要确保这些步骤在Python中的实现正确无误。同时,需要处理输入输出,尤其是多行输入的情况。例如,题目可能给出多个测试用例,或者在单次运行中处理多个操作指令。 考虑到用户提供的引用中,引用[2]提到了处理输入数据的难点,即如何处理以空格或换行分隔的数据。因此,在处理每个操作指令时,需要正确解析参数,特别是当参数中包含字符串时,可能需要读取整行然后拆分。例如,对于插入操作,读取整行,然后分割成操作类型、位置和插入的字符串。例如,使用input().split(' ', 2)来分割前两个参数(操作类型和位置),剩下的部分作为插入的字符串,即使其中有空格也能正确获取。 接下来,编写代码的大致步骤: 1. 读取初始字符串。 2. 读取操作次数n。 3. 循环n次处理每个操作: a. 读取操作指令行。 b. 根据操作类型分割参数。 c. 执行对应的字符串操作。 例如,对于操作1(插入): 指令行可能是“1 8 what”,其中8是位置,后面是插入的字符串。使用split(' ', 2)得到列表['1','8','what'],然后转换为int类型的位置和字符串。 对于操作2(删除): 指令行可能是“2 5 3”,表示从位置5开始删除3个字符。此时split()得到三个部分,转换为操作类型,起始位置和删除长度。 对于操作3(替换): 可能需要三个参数,例如“3 old_str new_str”,将所有的old_str替换为new_str。使用split(' ', 2)分割为操作类型,old_str和new_str。 对于操作4(查找): 指令可能是“4 target_str”,需要返回首次出现的位置。 需要注意的是,题目中的位置可能从0开始还是1开始,例如,在删除操作中,假设原字符串是s,从位置pos开始删除长度为l,那么在Python中对应的分片是s[:pos] + s[pos+l:],但需要确认题目中的位置定义。例如,如果题目中的位置从0开始,那么直接使用;如果从1开始,则需要调整pos减1。 另外,替换操作可能需要区分大小写,题目是否有说明。根据题目描述,P5734可能不涉及大小写问题,所以直接替换即可。 现在,结合以上分析,可以开始编写Python代码的框架: 读取初始字符串s = input().strip() 读取操作次数n = int(input()) 循环n次: op_line = input().strip() op = op_line[0] if op == '1': # 插入操作 parts = op_line.split(' ', 2) pos = int(parts[1]) insert_str = parts[2] s = s[:pos] + insert_str + s[pos:] elif op == '2': # 删除操作 parts = op_line.split(' ') pos = int(parts[1]) length = int(parts[2]) s = s[:pos] + s[pos+length:] elif op == '3': # 替换操作 parts = op_line.split(' ', 2) old_str = parts[1] new_str = parts[2] s = s.replace(old_str, new_str) elif op == '4': # 查找操作 parts = op_line.split(' ', 1) target = parts[1] print(s.find(target)) # 操作完成后可能需要输出当前字符串,根据题目要求 但需要仔细核对题目要求,例如,每个操作执行后是否需要输出结果。根据题目P5734的描述,可能只有在查找操作(操作4)时需要输出结果,其他操作不输出。例如,操作4会输出子串的位置,而其他操作执行后不需要输出,但需要更新字符串。 此外,还需要考虑边界情况,比如删除操作中的pos和length是否超过字符串长度。例如,当pos+length超过字符串长度时,应只删除到末尾。在Python中,分片超出范围不会报错,因此可以直接处理。 例如,在删除操作中: s = s[:pos] + s[pos+length:] 是正确的,即使pos+length超过len(s),s[pos+length:]会返回空字符串,因此没问题。 对于插入操作的位置pos,必须满足0 <= pos <= len(s),否则可能出错。题目可能保证输入的合法性,但代码中最好处理一下。 替换操作中,replace方法会替换所有出现的子串,所以直接使用即可。 最后,根据题目要求,每个操作执行后,除了操作4需要输出查找结果外,其他操作不需要输出。例如,执行完操作4后,输出找到的位置。 现在,综合以上分析,写出完整的Python代码: s = input().strip() n = int(input()) for _ in range(n): op_line = input().strip() op = op_line[0] if op == '1': # 插入操作:格式是 1 pos str,pos是插入的位置,插入后原位置的字符后移 # 例如,原字符串是 'abc',在位置1插入'xx',得到 'axxbc' parts = op_line.split(' ', 2) pos = int(parts[1]) insert_str = parts[2] s = s[:pos] + insert_str + s[pos:] elif op == '2': # 删除操作:格式是 2 pos len,删除从pos开始的len个字符 parts = op_line.split() pos = int(parts[1]) length = int(parts[2]) s = s[:pos] + s[pos+length:] elif op == '3': # 替换操作:格式是 3 old new,将所有old替换为new parts = op_line.split(' ', 2) old = parts[1] new = parts[2] s = s.replace(old, new) elif op == '4': # 查找操作:格式是 4 target,输出第一次出现的位置,否则-1 parts = op_line.split(' ', 1) target = parts[1] print(s.find(target)) 需要注意的是,这里的插入操作中的pos是否从0开始。例如,如果题目中的位置是插入到第pos个字符之后,那么可能需要调整。比如,如果原题中的插入位置是指在第pos个字符后面插入,比如原字符串是abcd,插入到位置1后面,则变成ab插入字符串后变成a插入字符串b后面的部分。但根据题目描述,可能pos是插入的起始位置,比如插入到pos位置,那么原字符串的位置pos之后的字符后移。例如,假设pos是0,插入到开头,那么s[:0]是空字符串,插入新字符串后接原字符串。 需要确认题目中的具体定义。根据P5734的题目描述,例如,操作1的描述是:在文档中插入一个字符串,输入格式为1 pos str,表示在插入位置pos后面插入str。这里的pos可能指的是从0开始的索引,或者从1开始。例如,如果原字符串是abc,插入到位置0后面,则变成a插入的字符串后接bc。或者,pos是插入的位置,比如在位置0插入,那么插入的字符串放在原字符串的开头。 可能题目中的pos是插入的位置索引,从0开始。例如,原字符串是abc,插入到位置0,那么插入的str会在位置0后面,即变成a插入的str后接bc。例如,假设原字符串s的长度是n,pos的有效范围是0到n,插入后新字符串的长度是n + len(str)。 因此,代码中的处理是正确的,即s[:pos] + str + s[pos:]。 测试样例可能需要验证。例如,原题可能提供测试用例: 例如,初始字符串是:ILove 操作1:1 1 Luogu → 在位置1插入Luogu,得到ILuoguLove 操作2:2 5 3 → 删除从位置5开始的3个字符,假设删除后的字符串是ILuogve(需要具体计算) 操作3:3 Love Luo → 将Love替换为Luo,得到ILuogLuo 操作4:4 Luo → 查找位置,输出对应的索引。 不过,可能具体测试案例需要更详细的数据,但这里的关键是确保代码逻辑正确。 另外,关于输入的处理,例如操作1的参数是否可能包含空格。例如,插入的字符串本身含有空格,这时候split(' ', 2)可以正确分割,因为第三个参数是剩余的部分。例如,输入行是“1 3 hello world”,那么split(' ', 2)得到['1', '3', 'hello world'],这样插入的字符串就是'hello world',正确。 对于操作3,例如替换操作,如果参数是“3 ab cd”,则split(' ', 2)得到['3','ab','cd'],将所有的'ab'替换为'cd',正确。 综上,代码应该是正确的。</think>### P5734 【深基6.例6】文字处理软件 Python题解 #### 题目分析 题目要求模拟一个文字处理软件,支持插入、删除、替换和查找子串操作。Python的字符串操作能直接满足需求,但需注意输入参数的处理,尤其是带空格的字符串参数。 #### 解题思路 1. **输入处理**:读取初始字符串和操作指令,需使用`split(' ', maxsplit)`分割参数,确保带空格的字符串参数不被错误分割。 2. **插入操作**:将字符串插入到指定位置,使用字符串切片实现。 3. **删除操作**:删除从指定位置开始的若干字符,同样用切片处理。 4. **替换操作**:使用`str.replace()`方法全局替换子串。 5. **查找操作**:使用`str.find()`返回子串首次出现的位置。 #### 代码实现 ```python s = input().strip() n = int(input()) for _ in range(n): op_line = input().strip() op = op_line[0] if op == '1': # 插入操作:1 pos str _, pos, insert_str = op_line.split(' ', 2) pos = int(pos) s = s[:pos] + insert_str + s[pos:] elif op == '2': # 删除操作:2 pos len _, pos, length = op_line.split() pos, length = int(pos), int(length) s = s[:pos] + s[pos+length:] elif op == '3': # 替换操作:3 old new _, old_str, new_str = op_line.split(' ', 2) s = s.replace(old_str, new_str) elif op == '4': # 查找操作:4 target _, target = op_line.split(' ', 1) print(s.find(target)) ``` #### 代码说明 - **插入操作**:通过`split(' ', 2)`分割出位置和插入字符串,确保含空格的字符串被完整读取。 - **删除操作**:直接计算删除后的切片,若超出字符串长度会自动截断。 - **替换操作**:使用`replace`方法全局替换所有匹配的子串。 - **查找操作**:`find`方法返回首次出现的索引,未找到时返回`-1`[^1][^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值