python刷题
时间:2023-04-23 01:37:00
#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' 2018.1.30 Python 练习100题 http://www.runoob.com/python/python-100-examples.html ''' ''' 主题001:有四个数字:1、2、3、4,能形成多少个不同且无重复数字的三位数?各有多少? ''' def tm001(): ''' 【个人备注】:按题意直接写 ''' arr = [] for i in range(1,5): for j in range(1,5): for k in range(1,5): num = 100*i 10*j k if i!=j and j!=k and i!=k and num not in arr:# 三位数不同,不重复数字 arr.append(num) print(len(arr),arr) def tm001_1(): ''' 【个人备注】:其实python可直接调用自带排列组合模块。 我也知道这个写法,但是函数记不住,百度一下子就能写出来。 假如这是面试题,能写出后一个当然好,不能的话还是老老实实遵循以上思路吧。 itertools我在这里整理了排列组合的用法。 itertools 实现 组合、排列、组合(放回)、笛卡尔积 https://blog.csdn.net/watfe/article/details/80108774 ''' import itertools temp_arr = list(itertools.permutations([1, 2, 3, 4], 3)) # 排列 # A_4^3 = (4)!(4-3)! = (4*3*2*1)/1 = 24 arr = [100*t[span class="token number">0]+10*t[1]+t[2] for t in temp_arr]
print(len(arr),arr)
''' 题目002:企业发放的奖金根据利润(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,求应发放奖金总数? '''
def tm002():
''' 程序分析:请利用数轴来分界,定位。 【个人备注】:这种处理数轴问题的写法,值得参考。比elif的写法,简洁方便的多。 '''
money = int(input('净利润:'))
arr = [1000000,600000,400000,200000,100000,0]
rat = [0.01,0.015,0.03,0.05,0.075,0.1]
bonus = 0
for i in range(len(arr)):
if money>arr[i]: # 对于处于区间的部分
bonus+=(money-arr[i])*rat[i] # 计算并累加奖励
money=arr[i] # 剩余部分
print(bonus)
''' 题目003:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? '''
def tm003():
''' 【个人备注】:网站上是求了一下方程,没细看。 python又不是没有开方函数,直接按字面意思解了。 2019-8-20 感谢Xueyang_Liu指出取值区间问题,进行修改。满足题意的数值不止一个两个。 考虑到取值区间,根据题意: 一个整数(m)加上100后是一个完全平方数 => m+100>=0,所以m>=-100,m取值下限为-100; 两个完全平方数的差是168,由于y=x**2这样的二次函数的图象是开口向上的抛物线,函数在x>0区间内单调递增,其导数可知两个相邻值y2-y1差值会越来越大 => (x+1)**2-x**2<=168,得x<=83.5。由于m=x**2-100,所以大约是m<7000的样子。 这样整数m的取值范围可以限定为[-100,7000] '''
import math
for i in range(-100,7000):
m = math.sqrt(i+100)
n = math.sqrt(i+100+168)
if m%1==0 and n%1==0:
print(i)
''' 最终会得到4个满足条件的整数: -99 21 261 1581 '''
def tm003_1():
''' 如果不想使用开方函数,也可以使用Xueyang_Liu的方法也行。根据之前的推论x<=83.5,所以实际取值范围可以写成x<84。 '''
arr=[]
result=[]
for i in range(84):
arr+=[i**2]
for elem in arr:
if elem+168 in arr:
result+=[elem-100]
return result
''' 题目004:输入某年某月某日,判断这一天是这一年的第几天? '''
def tm004():
''' 【个人备注】:知道python有时间元组这一概念,这道题完全不需要计算。 时间元组包含九个属性 tm_year 年 tm_mon 月(1~12) tm_mday 日(1~31) tm_hour 时(0~23) tm_min 分(0~59) tm_sec 秒(0~61, 60或61是闰秒) tm_wday 星期(0~6, 0是周一) tm_yday 第几天(1~366, 366是闰年) tm_isdst 夏令时(1夏令时、0非夏令时、-1代表未知。平时写代码基本用不到。夏时令是指部分国家地区,夏季人为将时间调快一小时,早睡早起,以便充分利用夏日光照,节约用电。中国从1992年起就没有再执行过这个了) '''
import time
date = input('输入时间(例如2018-01-23):')
st = time.strptime(date,'%Y-%m-%d') # 时间文本转化成时间元祖
num = st.tm_yday
print(num)
''' 题目005:输入三个整数x,y,z,请把这三个数由小到大输出。 '''
def tm005():
print('输入三个整数')
x = int(input('输入第1个整数:'))
y = int(input('输入第2个整数:'))
z = int(input('输入第3个整数:'))
l = [x,y,z]
arr = sorted(l) # 你也可以使用list.sort()方法来排序,此时list本身将被修改
print(arr)
''' 题目006:斐波那契数列。 '''
def tm006():
''' 程序分析:斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……。 【个人备注】:很多种解法,我是按照分割的方式,每次取列表后两项,然后相加。 '''
l = [0,1]
for i in range(10):
arr = l[-2:]
l.append(arr[0]+arr[1])
print(l)
''' 题目007:将一个列表的数据复制到另一个列表中。 '''
def tm007():
''' 【个人备注】:如果系统的看过python教程之类的应该都知道。 Python里面一切都是对象,list的复制需要用a[:]或a.copy()的方式。 至于b=a只是相当于给a取了个别名而已,指向的是同一个列表,并没有实现复制。 '''
a = [1, 2, 3]
b = a[:]
'''题外话'''
a[0]=0
print(id(a),id(b)) # 可以看到a,b的内存不一致,是复制
print(a,b) # 修改a,b不变
a = [1, 2, 3]
b = a
a[0]=0
print(id(a),id(b)) # 如果去掉[:],可以看到a,b的内存一致,并没有复制,指向的是同一个列表
print(a,b) # 修改a,b也变
def tm007_1():
''' 2022-02-08 补充: 其实a.copy()也只是浅拷贝,如果a是list内嵌套多层list的形式,则嵌套的内容还是对象 举个例子: '''
import copy
a = [[0],[1]]
b = a.copy()
c = copy.deepcopy(a)
print(id(a),id(a[0]))
print(id(b),id(b[0]))
print(id(c),id(c[0]))
''' 输出: 1638598258752 1638598253952 # 虽然a、b不同 1638598254400 1638598253952 # 但a[0]、b[0]是同一个对象;此时a[0]修改b[0]也会变 1638598259008 1638598252672 # 只有深拷贝才是完全不同的对象 '''
''' 题目008:题目:输出 9*9 乘法口诀表。 '''
def tm008():
''' 【个人备注】:已经忘了,百度了才想起来口诀表具体长什么样。 注意 %-7s 和 end='' 的用法,其他没什么。 '''
for i in range(1,10):
for j in range(1,10):
if j<=i:
string = '%d*%d=%d'%(j,i,j*i)
print('%-7s'%string,end='')
print('')
def tm008_1():
''' csdn用户isgoto用format方法生成字符串,也可以参考。 用循环到i+1的方法,比上面还能少写一行。 '''
for i in range(1,10):
for j in range(1, i + 1):
print("{0} * {1} = {2}".format(i, j, i * j),end="\t")
print()
''' 题目009:暂停一秒输出。 '''
def tm009():
''' 【个人备注】:time.sleep(),用过的都知道。 '''
import time
a = time.time()
time.sleep(1)
b = time.time()
print(b-a)
''' 题目010:暂停一秒输出,并格式化当前时间。 '''
def tm010():
''' 【个人备注】:时间格式化用过几次,用过就忘。关于时间处理的更多内容可以看tm016。 '''
import time
a = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) # time.localtime()时间戳转化成时间元祖
print(a)
time.sleep(1)
b = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) # time.strftime()时间元祖转化成时间文本
print(b)
''' 题目011:古典问题: 有一对兔子, 从出生后第3个月起每个月都生一对兔子, 小兔子长到第三个月后每个月又生一对兔子。 假如兔子都不死。 问每个月的兔子总数为多少? '''
def tm011():
''' 其实这道题就是斐波那契数列的由来。 【个人备注】:理清思路是关键,理解成满两个月后,每月都能生兔子,就好办了。 '''
m1=1 # 满月
m2=0 # 满俩月(下个月生兔子)
mm=0 # 可以月月生兔子了
for i in range(1,10):
# 过了1个月后
mm = mm+m2 # 加入新增成年的兔子
m2 = m1 # 满月的变成满俩月
m1 = mm # 这个月新出生兔子
print(i,mm+m1+m2) # 每个月有多少对兔子
''' 题目012:判断101-200之间有多少个素数,并输出所有素数。 '''
def tm012():
''' 【个人备注】:按照素数(也叫质数[2,3,5,7,11,13,17,19,...])不能被之前的素数整除,取200以内所有素数,然后取出101-200之间的部分。 '''
arr = [2,3]
# 取200以内所有素数
for i in range(4,201):
for j in arr:
if i%j==0:
break
# else: # 这是一开始我自己的写法,后来发现for可以直接接else子语句
# if j==arr[-1]:
# arr.append(i)
else: # 迭代的对象成功迭代完,位于else的子句将执行;而如果在for循环中含有break时则直接终止循环,并不会执行else子句。
arr.append(i)
# 取出100-200之间部分
for i in range(len(arr)):
if arr[i]>100:
l = arr[i:]
print(len(l),l)
break
''' 题目013:打印出所有的"水仙花数", 所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。 例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。 '''
def tm013():
''' 【个人备注】: // 取整,% 求余,**3 三次方。知道取整求余写法的就没问题。 '''
for i in range(100,1000):
b = i//100 # 百位
s = i%100//10 # 十位
g = i%10 # 个位
if b**3+s**3+g**3==i:
print(i)
''' 题目014:将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。 '''
def tm014():
''' 【个人备注】:拆到拆不动为止,类似012题。 '''
import math
num = int(input('输入一个整数:'))
arr = []
while num>1:
for i in range(2,int(math.sqrt(num))+1): # 因为题目是一个没写范围正整数,开方可以有效减少该值过大时候的计算量
if num%i==0:
arr.append(i)
num = num//i
break
else:
arr.append(num)
break
print(arr)
''' 题目015:利用条件运算符的嵌套来完成此题:学习成绩>=90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。 '''
def tm015():
''' 【个人备注】:if-else基本用法,没啥说的。 '''
score = float(input('输入一个成绩:'))
if score>=90:
print('A')
elif score>=60:
print('B')
else:
print('C')
''' 题目016:输出指定格式的日期。 '''
def tm016():
''' 【个人备注】:用的不多经常忘,整理了一下参考答案和一些转换 2019-5-29 以下日期时间代码仅供参考。 我将常用的日期时间方法,整理到了我的另一篇博客中 《Python3 日期文本互转,时间戳,时间差 以及 时区变换》 https://blog.csdn.net/watfe/article/details/84943732 '''
import time
print(time.time()) # 时间戳 1498539133.655
print(time.localtime()) # 时间元祖 tm_year=2017, tm_mon=6, tm_mday=27, tm_hour=12, tm_min=53, tm_sec=16, tm_wday=1, tm_yday=178, tm_isdst=0
print(time.asctime()) # 时间的一种可读文本形式 'Tue Jun 27 12:53:50 2017'
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())) # 按指定文本格式输出时间 '2017-06-27 13:00:57'
st = time.localtime(time.time()) # 时间戳 转化成 时间元祖
st = time.strptime('2018/1/23','%Y/%m/%d') # 时间文本 转化成 时间元祖
date = time.strftime('%Y-%m-%d',st) # 时间元祖 转化成 时间文本 '%Y-%m-%d %H:%M:%S'
print(date) # 前面两条函数配合着用,相当于将时间文本重新格式化。
''' 题目017:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。 '''
def tm017():
''' 【个人备注】:本来想写成这种格式来着 import string if c in string.ascii_letters: # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ if c == ' ': # 空格 if c in string.digits: # 0123456789 看了参考答案才知道有现成的函数可以用。 其实随便哪种都行,甚至直接把一串字母粘上去看起来更直接。 '''
s = input('input a string:\n')
letters,space,digit,others = 0,0,0,0
for c in s:
if c.isalpha():
letters += 1
elif c.isspace():
space += 1
elif c.isdigit():
digit += 1
else:
others += 1
print('char = %d,space = %d,digit = %d,others = %d' % (letters,space,digit,others))
''' 题目018:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制。 '''
def tm018():
''' 【个人备注】:答案给的解法很多种,但是我还是认为我写的方法最简单。 2+22+222+2222+22222 可以理解为: 20000 + 2*2000 + 3*200 + 4*20 + 5*2 也就是: 1*2*10^4 + 2*2*10^3 + 3*2*10^2 + 4*2*10^1 + 5*2*10^0 所以简单迭代就可以出结果 '''
a = 2
t = 5
num = 0
for i in range(1,t+1):
num+=i*a*(10**(t-i))
print(num)
''' 题目019:一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如6=1+2+3.编程找出1000以内的所有完数。 '''
def tm019():
''' 【个人备注】:题意看的不是太懂,于是百度了一下:完数就是除了自身之外的所有约数之和等于他本身。 第一个完全数是6,它有约数1、2、3、6,除去它本身6外,其余3个数相加,1+2+3=6。 第二个完全数是28,它有约数1、2、4、7、14、28,除去它本身28外,其余5个数相加,1+2+4+7+14=28。 终于看懂了题意。 先求出所有约数,然后求和比一下是否相等就行了,没有难度 '''
for num in range(1,1000):
arr = []
for i in range(1,num):
if num%i==0:
arr.append(i)
if sum(arr)==num:
print(num,arr)
''' 题目020:一球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在第10次落地时,共经过多少米?第10次反弹多高? '''
def tm020():
''' 【个人备注】:很简单,没啥说的 '''
total = 0
m = 100 # 第一次落地,经过了一百米
total += m
for i in range(10-1): # 之后9次弹起到落地
m = m/2 # 弹起的高度
total += 2*m # 弹起然后重新落地,一共经过的距离
print(total)
print(m/2)
''' 题目021:猴子吃桃问题 猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。 以后每天早上都吃了前一天剩下的一半零一个。 到第10天早上想再吃时,见只剩下一个桃子了。 求第一天共摘了多少。 '''
def tm021():
''' 【个人备注】:第十天num=1个,第九天必然是4个:4/2-1=1,也就是(num+1)*2=4。 做这种题,先用算数式列出来,然后用代码描述就行了。 '''
num = 1
for i in range(10-1):
num = (num+1)*2
print(num)
''' 题目022:两个乒乓球队进行比赛,各出三人。 甲队为a,b,c三人,乙队为x,y,z三人。 已抽签决定比赛名单。有人向队员打听比赛的名单。 a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单。 '''
def tm022():
''' 【个人备注】:列出两个队伍, 然后用排列组合函数列出所有组合, 再排除不满足条件的 写出来后看了一眼参考答案, 才发现自己写不如参考答案便于理解 '''
import itertools
jia = ['a','b','c']
yi = ['x','y','z']
arr = [[''.join(j) for j in list(zip(jia,i))] for i in list(itertools.permutations(y