求阶乘

代码如下:
python
import sys
sys.setrecursionlimit(10**6)
dic = {0:1}
def f(n):
if n in dic.keys():
return dic[n]
else:
dic[n] = n * f(n - 1)
return dic[n] % 998244353
n = int(input())
print(f(n))

错误示例:
RTE

RTE

MLE

TLE

斐波那契数列Ⅰ

代码如下:
python
#法一:
def f(n):
if n == 1 or n == 2:
return 1
else:
return f(n - 1) + f(n - 2)
n = int(input())
print(f(n))
python
法二:
dic = {1: 1, 2: 1}
def f(n):
if n in dic.keys():
return dic[n]
else:
dic[n] = f(n - 1) + f(n - 2)
return dic[n]
n = int(input())
print(f(n))
分形




代码如下:
python
def B(n):
if n == 1:
return ['X']
pre = B(n - 1)
size = len(pre)
# 上半部分:B(n-1) + 空格 + B(n-1)
top = [a + ' ' * size + b for a, b in zip(pre, pre)]
# 中间部分:空格 + B(n-1) + 空格
mid = [' ' * size + a + ' ' * size for a in pre]
# 下半部分:B(n-1) + 空格 + B(n-1)
bottom = [a + ' ' * size + b for a, b in zip(pre, pre)]
return top + mid + bottom
def main():
while True:
try:
n = int(input())
if n == -1:
break
ans = B(n)
for row in ans:
print(row)
print('-')
except EOFError:
break
if __name__ == '__main__':
main()
- 为什么不能直接 top = [pre + ' ' * size + pre]
· pre 是一个列表,例如当 n=2 时, pre 是 ['x x', ' x', 'x x'] 。
· 列表和字符串不能直接用 + 号拼接,Python 会报错: TypeError: can only concatenate list (not "str") to list 。
· 即使想把列表当成字符串处理,也会得到错误的结构,因为我们需要的是逐行拼接,而不是把整个列表当成一个整体。
- 为什么要用 zip(prev, prev)
· zip(prev, prev) 的作用是把 prev 列表中的每一行,和它自己配对成元组 。
例如 prev = ['a', 'b', 'c'] , zip(prev, prev) 会得到 [('a', 'a'), ('b', 'b'), ('c', 'c')] 。
· 然后用列表推导式 [a + ' ' * size + b for a, b in zip(prev, prev)] ,就可以把每一行 a 和 b (其实是同一行)用空格拼接起来,得到新的一行。
- 举个具体例子(n=2)
· n=1 时, prev = ['x'] , size = 1 。
· top = [a + ' ' * 1 + b for a, b in zip(prev, prev)] → ['x x'] 。
· mid = [' ' * 1 + line + ' ' * 1 for line in prev] → [' x '] 。
· bottom = ['x x'] 。
汉诺塔问题


代码如下:
python
def hanoi(n, start, midpoint, target):
if n == 1:
print(f"Move disk 1 from {start} to {target}")
return
# 将 n-1 个盘子从 start 借助 target 移动到 midpoint
hanoi(n -1, start, target, midpoint)
# 移动第 n 个盘子
print(f"Move disk {n} from {start} to {target}")
# 将 n-1 个盘子从 midpoint 借助 start 移动到 target
hanoi(n - 1, midpoint, start, target)
n = int(input())
# 调用函数,A 是起始柱,C 是目标柱,B 是辅助柱
hanoi(n, 'A', 'B', 'C')
斐波那契数列Ⅱ

代码如下:
python
def pre_fib(max_n):
fib = [0] * (max_n + 1)
fib[1] = fib[2] = 1
for i in range(3, max_n + 1):
fib[i] = (fib[i - 1] + fib[i - 2]) % 998244353
return fib
max_n = 10000
fib = pre_fib(max_n)
t = int(input())
for i in range(t):
n = int(input())
print(fib[n])
优势:
-
一次计算,多次使用 - 适合处理多个测试用例
-
没有递归深度问题
-
时间复杂度 O(MAX_N),查询时间复杂度 O(1)
-
内存友好 - 只需要一个列表存储结果
错误示例:
python
from functools import lru_cache
@lru_cache(maxsize=None)
def f(n):
if n == 1 or n == 2:
return 1
return (f(n - 1) + f(n - 2)) % 998244353
t = int(input())
for i in range(t):
n = int(input())
print(f(n))

python
dic = {1:1, 2:1}
def f(n):
if n in dic.keys():
return dic[n]
dic[n] = f(n - 1) + f(n - 2)
return dic[n]
t = int(input())
for _ in range(t):
n = int(input())
print(f(n) % 998244353)

python
dic = {1:1, 2:1}
def f(n):
if n in dic.keys():
return dic[n]
dic[n] = f(n - 1) + f(n - 2)
return dic[n] % 998244353
t = int(input())
for _ in range(t):
n = int(input())
print(f(n))

python
def f(n):
if n == 1 or n == 2:
return 1
return (f(n - 1) + f(n - 2)) % 998244353
t = int(input())
for i in range(t):
n = int(input())
print(f(n))

滑雪


代码如下:
python
import sys
sys.setrecursionlimit(10**6)
R, C = map(int, input().split())
mapp = []
for i in range(R):
mapp.append(list(map(int, input().split())))
# 记忆化数组,dp[i][j] 表示从 (i,j) 出发的最长滑坡长度
dp = [[-1] * C for _ in range(R)]
def dfs(x, y):
if dp[x][y] != -1:
return dp[x][y] #记忆化,避免重复计算
max_len = 1#自己本身算一个长度
dic = [(0, -1), (0, 1), (-1, 0), (1, 0)]
for i in range(4):
xx, yy = x + dic[i][0], y + dic[i][1]
if xx < 0 or xx >= R or yy < 0 or yy >= C:
continue
if mapp[xx][yy] < mapp[x][y]:
max_len = max(max_len, dfs(xx, yy) + 1)
dp[x][y] = max_len
return max_len #返回结果,给上一层调用者
# 计算所有点的dp值
for i in range(R):
for j in range(C):
dfs(i, j)
# 直接找dp表中的最大值
ans = 0
for i in range(R):
for j in range(C):
ans = max(ans, dp[i][j])
print(ans)
01背包

代码如下:
python
n, V = map(int, input().split())
dp = [0] * (V + 1)
for i in range(1, n + 1):
vi, wi = map(int, input().split())
for j in range(V, vi - 1, -1):
dp[j] = max(dp[j], dp[j - vi] + wi)
print(dp[V])
爬楼梯

代码如下:
递归法
python
from functools import lru_cache
@lru_cache(maxsize=None)
def dfs(n):
if n == 1:
return 1
elif n == 2:
return 2
return dfs(n - 1) + dfs(n - 2)
n = int(input())
print(dfs(n))
动态规划:
python
def climb_stairs(n):
if n == 1:
return 1
if n == 2:
return 2
dp = [0] * (n + 1)
dp[1] = 1
dp[2] = 2
for i in range(3, n + 1):
dp[i] = dp[i - 1] + dp[i - 2]
return dp[n]
n = int(input())
print(climb_stairs(n))