mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6mobile wallpaper 7
1031 字
3 分钟
【实践3】算法应用(递归、分治、递推、排序、贪心、随机)
2025-12-01

1.【递归法】Fibonacci 数列#

Fibonacci 数列是一个经典的数学序列,其定义如下:第 1 项为 1,第 2 项为 1,从第 3 项开始,每一项都等于前两项之和。即:F(1) = 1,F(2) = 1,F(n) = F(n-1) + F(n-2)(当 n ≥ 3)。#

编写一个程序,生成 Fibonacci 数列的前 n 项,并输出结果。#

def Fibonacci(n):
if n==1 or n==2:
return 1
else:
return Fibonacci(n-1)+Fibonacci(n-2)
n=eval(input())
for i in range(1,n+1):
print(Fibonacci(i))

2.【分治法】二分查找#

二分查找是一种在有序数组中查找特定元素的高效算法。它的基本思想是:每次将查找区间缩小一半,通过比较中间元素与目标值的大小来决定下一步查找的范围。由于每次比较后都能排除一半的数据,因此时间复杂度为 O(log n),远优于线性查找的 O(n)。使用该算法的前提是数组必须已经按升序或降序排列。查找过程中需维护两个指针,分别指向当前查找区间的起始和结束位置,然后不断调整这两个边界直到找到目标或确定其不存在。#

guessKey=eval(input('')) #用户输入0-999之间的数,作为被查找的数字
L=list(range(1000)) #产生序列0-999的等差数列
left= 0
right=len(L)-1
#请开始编程
while left<=right:
mid=(left+right)//2
print("left:{},right:{},mid:{}".format(left,right,mid))
if L[mid]>guessKey:
right=mid
elif L[mid]<guessKey:
left = mid
else :
break
print(mid, L[mid]) #打印输出

3.【递推法】逆推法计算炮弹的储备数#

本题本质上是一个逆向递推问题。每天的操作是:使用当前数量的一半多一枚,即剩余量 = 当前总量 - (当前总量 ÷ 2 + 1)= 当前总量 ÷ 2 - 1。但为了求初始值,我们需要从最后一天的状态倒推回去。已知第10天开始时剩下1枚,说明第9天使用完毕后剩余1枚。那么第9天使用前的数量可以通过逆运算得到。设第 n 天结束时(即第 n+1 天开始时)剩余 r 枚,则第 n 天开始时的数量 x 满足:r= 2x −1变形得:x=2(r+1)利用这个公式,可以从最后一天的剩余数逐天向前推导,共推9天,即可得到第一天使用前的原始总数。#

#某军事基地储存了一批特殊炮弹,
#第一天使用了炮弹总数的一半多一枚,
#第二天又使用了剩下炮弹数量的一半多一枚,
#之后每天都使用前一天剩余炮弹数量的一半多一枚。
#到了第 10 天准备使用时只剩下一枚炮弹。
#计算最初炮弹的总量。
#返回第1天的炮弹总数
def calNum(day, count):
#请开始编程
for i in range(day-1, 0, -1):
count=2*(count+1)
return count
##############
day=10
count=1
print("炮弹总数量:",calNum(10, 1))

4.【贪心法】背包问题#

背包问题是一个经典的组合优化问题,其目标是在给定背包容量的前提下,选择一些物品放入背包,使得总价值最大化。每个物品有自己的重量和价值,背包只能承受一定重量的物品。#

编写一个程序,根据用户输入的物品重量和价值,以及背包容量,使用贪心法求解背包问题。#

#价值密度最小
def maxDensity(weight,value,bag):
sumWeight=0
sumValue=0
density=[value[i]/weight[i] for i in range(3)]
data=list(zip(weight, value, density))
data.sort(key=lambda x: x[2],reverse=True)
for i in data:
if sumWeight + i[0] <= bag:
sumWeight+=i[0]
sumValue+=i[1]
print("放入物品{},目前总价值:{},总体积:{}".format(i, sumValue, sumWeight))
else:
count=(bag-sumWeight)/i[0]
sumWeight+=i[0]*count
sumValue+=i[1]*count
print("放入物品{}{:.2f},目前总价值:{},总体积:{}".format(i,count, sumValue, sumWeight))
break
weight=[10, 20, 30]
value=[70, 100,180]
bag=50
maxDensity(weight,value,bag)

5.【排序】冒泡排序#

冒泡排序是一种简单的排序算法,它重复地遍历待排序的数列,依次比较相邻的两个元素,如果它们的顺序错误(如前面的数比后面的大),就交换它们的位置。这一过程持续进行,直到没有需要交换的元素为止,此时数列已经有序。每一轮遍历都会将当前未排序部分的最大值“冒泡”到正确的位置。该算法的时间复杂度为 O(n²),适用于数据量较小的排序场景。#

设计一个编程任务,要求实现冒泡排序算法,对一组无序的整数进行升序排列,并在每一轮排序过程中输出当前的状态,以便观察排序的执行过程。#

def bubbleSort(L):
#开始编程
n=len(L)
for i in range(n-1):
for j in range(n-1-i):
if L[j]<L[j+1]:
L[j],L[j+1]=L[j+1],L[j]
###################
return L
ls=[10,9,8,7,6,5,4,3,2,1,-1,54,34,-87]
print(bubbleSort(ls))

6.【随机化算法】求圆周率#

圆周率(π)是一个无理数,用于描述圆的周长与直径的比例。它的近似值为 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679。#

设计一个编程任务,要求使用随机化算法估计圆周率。具体来说,随机生成在单位正方形内的随机点,统计落在单位圆内的点的比例,从而估计圆周率。#

from random import random
from time import perf_counter
from math import sqrt
DARTS = 1000*1000
hits = 0.0
start = perf_counter()
pi = 0
for i in range(1, DARTS+1):
x, y = random(), random()
dist = sqrt(x**2 + y**2)
if dist <= 1.0:
hits = hits+1
pi = 4 * (hits/DARTS)
# 根据题目要求是要有下面两行的,但题目又说不需要输出结果,所以在提交时可以把下面两行删去或注释掉
print("圆周率值是: {}".format(pi))
print("运行时间是: {:.5f}s".format(perf_counter()-start))
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【实践3】算法应用(递归、分治、递推、排序、贪心、随机)
https://blog.sherry.qzz.io/posts/python/1201practice/
作者
Sherry
发布于
2025-12-01
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录