Python巩固基础-基础算法题目练习
一、有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少?
"""
1、写三个for循环,分别循环这四个数字,最内层的循环使用set的去重功能判断是否有重复数字、无则将数字拼接
2、将得到的数字放入一个set集合中,自动去重
3、集合元素的个数即为组成的数字个数
"""
res = set()
for x in range(1, 5):
for y in range(1, 5):
for z in range(1, 5):
if len({x, y, z}) == 3:
tmp = str(x) + str(y) + str(z)
res.add(tmp)
print('共组成{}个互不相同且无重复数字的三位数'.format(len(res)))
print('组成的数字如下:')
for i in sorted((list(res))):
print(i, end=' ')
二、企业发放的奖金根据利润提成。利润(I)低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,从键盘输入当月利润I,求应发放奖金总数?
"""
1、获取键盘输入作为利润,注意input获取的输入都为str类型,需要转换为float(注意不要转换为int,若利润有小数则会报错)
2、使用if..elif..条件语句进行判断利润是否在某个区间
3、通过该区间的奖金提成比例、计算对应的奖金数
4、单位为万,便于计算
"""
profit = float(input('请输入利润(单位为万):'))
if profit <= 10:
res = profit * 0.1
elif profit < 20:
res = 10 * 0.1 + (profit - 10) * 0.075
elif profit < 40:
res = 10 * 0.1 + 10 * 0.075 + (profit - 20) * 0.05
elif profit < 60:
res = 10 * 0.1 + 10 * 0.075 + 20 * 0.05 + (profit - 40) * 0.03
elif profit < 100:
res = 10 * 0.1 + 10 * 0.075 + 20 * 0.05 + 20 * 0.03 + (profit - 60) * 0.015
else:
res = 10 * 0.1 + 10 * 0.075 + 20 * 0.05 + 20 * 0.03 + 40 * 0.015 + (profit - 100) * 0.01
print('应发放奖金总数为:{}万'.format(res))
三、一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?
# 解法一
"""
1、完全平方数是非负数
2、一个正整数n是完全平方数的充分必要条件是n有奇数个因数(包括1和n本身)
3、如果正整数n的平方根是两个正整数,那么n是完全平方数
4、循环遍历0到10001,计算该数加上100、再加上168是否满足条件
"""
import math
for x in range(10001):
tmp1 = str(math.sqrt(x + 100)).split('.')[1]
if len(tmp1) == 1 and tmp1 == '0':
tmp2 = str(math.sqrt(x + 268)).split('.')[1]
if len(tmp2) == 1 and tmp2 == '0':
print(x)
# 解法二
"""
1、将0到100的平方存储在一个list中,
2、循环遍历0到10000,判断加上100、再加上168的数是否在这个list中,是则为需要的结果
"""
my_l = [i*i for i in range(10001)]
for x in range(10001):
if x + 100 in my_l:
if x + 268 in my_l:
print(x)
四、输入某年某月某日,判断这一天是这一年的第几天?
"""
1、将每一个月的天数存储在一个list中
2、先判断月份是否为1月,若是则直接输出天数
3、根据输入的年份判断是否闰年(能被4整除,但不能被100整除的是闰年,能被400整除的是闰年。)
3、若为闰年,二月为29天,平年则保持28天
4、将之前月份的天数加起来,再加上输入的日来计算总的天数,否则直接得出1月天数
"""
days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
in_date = input('请输入年月日(格式为20010120):')
year = in_date[:4]
month = in_date[4:6]
day = in_date[6:]
if int(month) == 1:
res = int(day)
else:
if (int(year) % 4 == 0 and int(year) % 100 != 0) or int(year) % 400 == 0:
days[1] = 29
sum_days = 0
for m in range(int(month) - 1):
sum_days += days[m]
res = sum_days + int(day)
print('这是这一年的第{}天'.format(res))
五、斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13,特别指出:第0项是0,第1项是第一个1。从第三项开始,每一项都等于前两项之和。打印前20个数
"""
1、定义一个初始值为[0, 1]的list
2、每一个新的元素为list[-1]+list[-2],循环18次,将新元素append到列表末尾
"""
init_list = [0, 1]
for x in range(18):
init_list.append(
init_list[-1] + init_list[-2]
)
print(init_list)
六、输出 9*9 乘法口诀表
"""
9*9乘法表如下:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
......
1*9=9 2*9=18 ......
观察可得:每一行都是从1开始计算,第n行就是从1到n去*n
1、总共9行,第一层for循环i从1到9
2、两层for循环,第二层循环从1到i进行运算,按照乘法表格式打印,直到x=i
"""
for i in range(1, 10):
for x in range(1, i+1):
print('{}*{}={}'.format(x, i, x*i), end=' ')
print('\n', end='')
七、有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
本题参考知乎https://www.zhihu.com/question/38045513下的回答
"""
1--1 1
2--1 1
3--1+1 大兔子生了一对小兔子a 2
4--1+1+1 a小兔子两个月了,大兔子再生一对b 3
5--1+1+1+1 +1 大兔子再生一对c,a三个月了生一对a-1,b两个月 5
6--1+1+1+1+1 +1+1+1 大兔子再生一对d,a再生一对a-2,b再生一对b-1 8
7--1+1+1+1+1+1 +1+1+1+1+1+1+1 大兔子再生一对e,a生一对,b生一对,c生一对,a-1再生一对 13
初始值兔子为1,年龄为1,过了两个月后增加兔子数为1,新兔子年龄为1,随着月数的增加,兔子年龄到3即可生育
1、因为每对兔子都有一个年龄,根据这个年龄来判断是否能生育,因此定义一个兔子对的类,有一个age属性
2、定义一个兔子对的list,初始值为1个兔子对,该兔子对年龄为1
3、循环月数,每一个月将兔子对的list中每个兔子对的年龄+1,遍历该list中的兔子对,若该兔子对年龄大于等于3,
则给兔子对的list增加一个新的兔子对
4、每个月的兔子对即为兔子对list的len
"""
# 定义一个兔子对的类,有一个age的属性,初始为0
class RabbitPair:
def __init__(self):
self.age = 0
def update(self):
self.age += 1
def rabbit_num(m):
# 初始的兔子数为一个兔子对
rabbits = [RabbitPair()]
# 循环月数,每个月将每对兔子年龄+1,并且模拟年龄到>=生育一对兔子
for m in range(m):
for rb in rabbits:
rb.update()
if rb.age >= 3:
rabbits.append(RabbitPair())
print(f'第{m+1}个月的兔子数为:{len(rabbits)}对')
month = int(input('请输入月数(正整数):'))
rabbit_num(month)
八、判断101-200之间有多少个素数,并输出所有素数。
"""
素数:指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数
1、循环遍历101-200之间的自然数
2、针对每个自然数,生成一个该自然数%从2到此数本身-1的数的结果list
3、如果list中有0,则该数不为素数
"""
result = []
for i in range(101, 201):
if 0 not in [i % j for j in range(2, i)]:
result.append(i)
print(f'101-200之间共有{len(result)}个素数,如下:')
print(result)
九、打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
"""
1、循环遍历100到999的自然数
2、将该数转换为字符串,取每一位的数转换为int进行计算,满足条件即为水仙花数
"""
for i in range(100, 1000):
unit = int(str(i)[0])
decade = int(str(i)[1])
hundred = int(str(i)[2])
if pow(unit, 3) + pow(decade, 3) + pow(hundred, 3) == i:
print(i)
十、将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5
。
"""
1、生成从2到number的质数
2、当number不为1的时候,不断进行循环;
3、针对质数进行for循环遍历,判断number和当前质数是否能整除;
4、若能整除,放入结果的list中,number变为整除后的结果
"""
number = int(input('请输入一个正整数:'))
res_str = str(number) + '='
prime_list = []
res_list = []
for n in range(2, number+1):
if 0 not in range(2, n):
prime_list.append(n)
while number > 1:
for p in prime_list:
if number % p == 0:
res_list.append(p)
number = number // p
break
print(res_str + '*'.join([str(r) for r in sorted(res_list)]))
十一、输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
"""
1、遍历此字符串;
2、针对每个字符进行判断,为对应的类型则进行计数;
"""
in_str = input('请输入一串字符:')
ens = 0
spaces = 0
nums = 0
others = 0
for s in in_str:
if s.isalpha():
ens += 1
elif s.isspace():
spaces += 1
elif s.isalnum():
nums += 1
else:
others += 1
print(f'该字符串共有{len(in_str)}个字符,其中:英文字母有{ens}个,空格有{spaces}个,数字有{nums}个,其他字符有{others}个')
十二、求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制。
"""
1、输入数字a和相加的个数n;
2、for循环,循环n次,根据a生成需要相加的数字,与前一个数字相加,最终得出结果。
"""
a = int(input('请输入正整数a:'))
n = int(input('请输入相加的个数n:'))
result = 0
for i in range(1, n+1):
result += int(str(a) * i)
print(f'result={result}')
十三、一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高?
"""
1、第一次落下的时候,经过100米,第一次反弹50米,给定此初始值;
2、后续每次落下,经过的总距离即为原先的距离加上上次反弹的距离乘2,反弹的高度为上次反弹的高度除以2;
3、需要注意,第一次落下的距离的计算方式与后续不同,因此可以给一个第一次落下和反弹的距离的初始值,后续再统一进行计算。
"""
def distance(times):
all_distance = 100
height = 50
for t in range(2, times+1):
all_distance += (height * 2)
height = height / 2
print(f'第{times}次落地时,共经过{all_distance}米,第{times}次反弹{height}米高')
十四、猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
"""
第10天还剩1个桃子
假设第9天有n个桃子,吃掉了n/2+1个桃子,还剩n-(n/2+1)即n/2-1个
假设第8天有m个桃子,吃掉了m/2+1个,还剩m-m/2+1即m/2-1个
循环9次,设初始桃子数为1,每次循环倒推前一天的桃子数
"""
peach = 1
for d in range(1, 10):
peach = (peach + 1) * 2
print(f'第{10-d}天有{peach}个桃子')
十五、30 个人在一条船上,超载,需要 15 人下船。于是人们排成一队,排队的位置即为他们的编号。报数,从 1 开始,数到 9 的人下船。如此循环,直到船上仅剩 15 人为止,问都有哪些编号的人下船了呢?
"""
1、初始化下船列表和最开始人员列表;
2、当下船人数不足15人时,不断循环;
3、每次循环整个列表时,初始化一个待下船人员的list、并使用count进行计数;
4、当count为9的倍数的时候所指向的人即为需要下船的人,将此人append到待下船列表;
5、循环一次列表结束后,删除待下船列表中的人员(不能边循环边删除,这样列表不断变化,循环时会出错);
最开始把题目理解错了,以为是循环了一次队列后从头开始重新报数,其实是相当于围成一个圈去不断的从1到9报数。
注意:不能边循环边删除,这样列表不断变化,循环时会出错,因此可以使用方法一循环一次后删除待下船的人,或者使用方法二,每次循环的是人员列表的copy,然后满足条件则删除人员列表中的人员
"""
# 方法一:循环一次后删除待下船的人
# off_people = []
# all_people = [i for i in range(1, 31)]
# count = 0
# while len(off_people) < 15:
# wait_off = []
# for i in all_people:
# count += 1
# if count % 9 == 0:
# off_people.append(i)
# wait_off.append(i)
# for w in wait_off:
# all_people.remove(w)
# 方法二:每次循环的是人员列表的copy,然后满足条件则删除人员列表中的人员
off_people = []
all_people = [i for i in range(1, 31)]
count = 0
while len(off_people) < 15:
people_copy = all_people[:]
for i in people_copy:
count += 1
if count % 9 == 0:
off_people.append(i)
all_people.remove(i)
print(off_people)
十六、设计一个计算器。可以简单计算2个数字之间的加减乘除。
def calculator():
num_a = float(input('请输入第一个数字:'))
operator = input('请输入运算符(+、-、*、/):')
num_b = float(input('请输入第二个数字:'))
if operator == '+':
return num_a + num_b
elif operator == '-':
return num_a - num_b
elif operator == '*':
return num_a * num_b
elif operator == '/':
if num_b == 0:
return '除数不能是0!'
return num_a / num_b
else:
return '输入的运算符有误!'
print(calculator())
十七、有一组不同高度的台阶,由一个整数数组表示,数组中每个数是台阶的高度。当开始下雨了(水足够多),台阶之间的水坑会积多少呢?
如下图,可以表示为数组[0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1],返回积水量6
"""
1、可以一层一层的计算,从数组第二位开始,找到有多少个中间是0,两边有台阶,即为这一层的积水量
2、数组中最大的数字即为最高的层数high,我们需要找high次
3、每次从数组第二位开始循环,若当前位台阶是0,判断前一位台阶是否为1,若为1,从当前位台阶向后寻找到不为0的台阶,其中的积水量即为不为0的台阶的位置与当前位的距离差
"""
nums = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
high = max(nums)
count = 0
list_len = len(nums)
for h in range(high):
tmp_list = [1 if i-(h+1) >= 0 else 0 for i in nums]
for x in range(1, list_len):
if tmp_list[x] == 0:
if tmp_list[x-1] > 0:
for y in range(x, list_len):
if tmp_list[y] > 0:
count += (y-x)
break
print(count)
十八、冒泡排序
"""
冒泡排序:它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。
走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
"""
def bubble_sort(nums):
str_nums = []
all_nums = []
for n in nums:
if isinstance(n, str):
str_nums.append(n)
if isinstance(n, int):
all_nums.append(n)
for _ in range(len(str_nums)):
for x in range(len(str_nums) - 1):
if str_nums[x] > str_nums[x + 1]:
tmp = str_nums[x]
str_nums[x] = str_nums[x + 1]
str_nums[x + 1] = tmp
for _ in range(len(all_nums)):
for x in range(len(all_nums) - 1):
if all_nums[x] > all_nums[x + 1]:
tmp = all_nums[x]
all_nums[x] = all_nums[x + 1]
all_nums[x + 1] = tmp
return str_nums + all_nums
print(bubble_sort([2, 4, 1, 'hi', 'aka', 88, 0, 32]))
十九、二分法插入排序
二十、随机生成100个3位数的整数,并分别打印出奇数之和、偶数之和。
import random
odds = []
evens = []
for _ in range(100):
num = random.randint(100, 999)
if num % 2 == 0:
evens.append(num)
else:
odds.append(num)
print(f'奇数之和:{sum(odds)}')
print(f'偶数之和:{sum(evens)}')
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构