pythontip 刷题记录

11.给你一个正整数列表 L, 输出L内所有数字的乘积末尾0的个数。(提示:不要直接相乘,数字很多,相乘得到的结果可能会很大)。

不能直接相乘会太大了,分解质因数,去找2和5的个数,取最小值

def solve_it():cont2=0cont5=0for i in L:while i%2 == 0:cont2 += 1i = i//2while i%5 == 0:cont5 += 1i= i//5return min(cont2,cont5) #your answerprint(solve_it())  # 答案需要输出

12.给你一个正整数列表 L, 判断列表内所有数字乘积的最后一个非零数字的奇偶性。如果为奇数输出1,偶数则输出0.。

注意看题目里是最后一位非0,

a = 1
for i in L:a *= i
while True:if a % 10 == 0:a = a // 10else:breakif a%2 ==0:print(0)
else:print(1)

13.给你一个整数a,数出a在二进制表示下1的个数,并输出。

b = bin(a)  # bin函数可以把数字转化为二进制
b = str(b)
s=0
for i in b:if i == '1':s +=1
print(s)

15.给定一个字符串a, 将a中的大写字母 转换成小写,其它字符不变,并输出。

例如:a=“aaaaaabbbDDDDD”

则输出:aaaaaabbbddddd

这题就很简单了,全都输出成小写就好了

print(a.lower())

16.银行在打印票据的时候,常常需要将阿拉伯数字表示的人民币金额转换为大写表示,现在请你来完成这样一个程序。

在中文大写方式中,0到10以及100、1000、10000被依次表示为: 零 壹 贰 叁 肆 伍 陆 柒 捌 玖 拾 佰 仟 万

以下的例子示范了阿拉伯数字到人民币大写的转换规则:

1 壹圆

11 壹拾壹圆

111 壹佰壹拾壹圆

101 壹佰零壹圆

-1000 负壹仟圆

1234567 壹佰贰拾叁万肆仟伍佰陆拾柒圆

现在给你一个整数a(|a|<100000000), 请你打印出人民币大写表示.

例如:a=1

则输出:壹圆

这段代码写的很好

dict = {'1':'壹','2':'贰','3':'叁','4':'肆','5':'伍','6':'陆','7':'柒','8':'捌','9':'玖','0':'零'}
dict_liang = {0:'',1:'拾',2:'佰',3:'仟'}
list_wrong = ['零仟','零佰','零拾','零零']
# 4 位 4 位的取就好了
def func(S): # 转换的函数,但如果第一位是0的话末尾还是会有个0,后面会剔除ans = ''for i in range(len(S) - 1,-1,-1):ans = ans + dict[S[i]] + dict_liang[i]for s_wrong in list_wrong:if s_wrong in ans:ans = ans.replace(s_wrong,'零')return ans
flag = 1
#a = -34009
if a < 0:flag = -1a = abs(a)
ans = ''
s = str(a)
s = s[::-1]#倒着做符合从个位往高位数的习惯
if len(s) <= 4:ans = func(s)
else:s1 = s[:4]s2 = s[4:]ans = func(s2) + '万' + func(s1)if '零万' in ans:ans = ans.replace('零万','万')  # fun函数的缺点就是如果你最后一位(反转后的第一位)是0的话,他的0没法在里面去除,所以这里要再去除一下
ans += '圆'
if '零圆' in ans:ans = ans.replace('零圆','圆')
if flag == -1:ans = '负' + ans
if a == 0:ans = '零圆'
print(ans)

17.给你两个正整数a,b, 输出它们公约数的个数。

from math import gcdc = gcd(a,b)
list1 = []
for i in range(1,c+1):if c % i == 0:list1.append(i)print(len(list1))

18.我们经常遇到的问题是给你两个数,要你求最大公约数和最小公倍数。今天我们反其道而行之,给你两个数a和b,计算出它们分别是哪两个数的最大公约数和最小公倍数。输出这两个数,小的在前,大的在后,以空格隔开。若有多组解,输出它们之和最小的那组。注:所给数据都有解,不用考虑无解的情况。

设两个数为 ac ad (a是最大公约数),那么现在就要找c和d,且c与d互质。
并且c d 最大不能超过 b//a。超过了话那 a*c 和a *d不就超过了 b嘛 ,那他们的最小公因数就不可能是b了。

a=3
b=60
list01 = []
m = max(a, b)
n = min(a, b)
l = m // n  #两个数相等要等于m*n 所以两个数一定都在n到m//n范围内,不小于n是肯定是,如果大于了m//n就证明有个数要小于n也不行
for i in range(1, l + 1):if l % i == 0:list01.append(i)
c = list01[len(list01) // 2]   # 取中间两个数是因为他们相加一般都是最小的
d = list01[len(list01) // 2 - 1]
print(d * n, c * n, end='')

19.给你一个字符串a,如果其中包含"LOVE"(love不区分大小写)则输出LOVE,否则输出SINGLE。

c=a.lower().count('love')
if c > 0:print("LOVE")
else:print('SINGLE')

20.给你个小写英文字符串a和一个非负数b(0<=b<26), 将a中的每个小写字符替换成字母表中比它大b的字母。这里将字母表的z和a相连,如果超过了z就回到了a。

运用ord和chr。ord()函数主要用来返回对应字符的ascii码,chr()主要用来表示ascii码对应的字符他的输入时数字

#a = "cagy"
#b = 3
list1 = []
for i in a:c = ord(i) + bif c >123:c = c % 123 +97list1.append(chr(c))
print(''.join(list1))

21.给你一个字符串a和一个正整数n,判断a中是否存在长度为n的回文子串。如果存在,则输出YES,否则输出NO。 回文串的定义:记串str逆序之后的字符串是str1,若str=str1,则称str是回文串,如"abcba".

flag = False
for i in range(len(a)):if i + n ==len(a):c = a[i:i+n]if c == c[::-1]:flag = Truebreakif flag :print('YES')
else:print('NO')

22.给你两个时间st和et(00:00:00<=st <= et<=23:59:59), 请你给出这两个时间间隔的秒数。 如:st=“00:00:00”, et=“00:00:10”, 则输出10.

s = [int(x) for x in st.split(':')]
e = [int(x) for x in et.split(':')]
sum = 0
sum1 = (e[0] - s[0])*60*60  # 正负这道题我们不用考虑,他是负的就负的好了
sum2 = (e[1] - s[1])*60
sum3 = e[2] - s[2]sum = sum1+sum2+sum3
print(sum)

23.一年有多少天,这是个大问题,很值得思考。现在给你一个年份year(year为四位数字的字符串,如"2008",“0012”), 你输出这一年的天数。如year=“2013”, 则输出365。

老生常谈了,可以搜一个闰年的定义

year  = int(year)
if year % 4 == 0 and (year % 100 != 0 or year % 400 ==0):print(366)
else :print(365)

24.下过象棋的人都知道,马只能走’日’字形(包括旋转90°的日),现在想象一下,给你一个n行m列网格棋盘, 棋盘的左下角有一匹马,请你计算至少需要几步可以将它移动到棋盘的右上角,若无法走到,则输出-1. 如n=1,m=2,则至少需要1步;若n=1,m=3,则输出-1。

# 列出x和y方向所有可能的走法 之后用zip 方便
dx = [1, 2, 2, 1, -1, -2, -2, -1]
dy = [-2, -1, 1, 2, 2, 1, -1, -2]
# 创建一个嵌套的列表,用来存储整个棋盘所有的点
# 类似于数组
# 列表表达式快速生成的,也可以用常规方法生成
# 这里注意一下:4*5的棋盘,代表有5*6个点
vis = [([0] * (m + 1)) for i in range(n + 1)]
# 创建一个列表,用来存储基于当前点位,所有等待访问的点的横坐标和纵坐标,以及本次走过的步长
# 因为有三个数据,所以列表里面嵌套一个元组
# 初始化都为0,代表从坐标轴原点开始 走
q = [(0,0,0)]
vis[0][0] = 1 #从原点开始,表示我们走过了# 只要有没有访问过的点并且能到达,就执行循环
while q:  # 因为q循环一次会弹出一个、temp = q.pop(0)# 判断是否到达终点,如果到达终点,则直接输出步长,代表走了多少步if temp[0] == n and temp[1] == m:print(temp[2])break# zip()函数:把两个列表变成一个列表+元组的形式# 遍历所有的走法for x,y in zip(dx,dy):# 这里,curx和cury分别代表了即将要走的点# 通过for循环,能把当前位置所有能走的点都遍历到curx = temp[0] + xcury = temp[1] + y# curstep放在这里,只有成功走了一个点,这个变量的值才会增加1curstep = temp[2] + 1if 0<= curx <= n and 0<= cury <= m and vis[curx][cury] != 1:# 未超出边界,或者未走过这个点,则标记为1,代表这个点走了vis[curx][cury] == 1# 把这个点和步长加入到q中,提供给下一次while循环使用,下一次循环就会从这个点开始往下走q.append((curx,cury,curstep))
else:print(-1)

25.给你一个时间t(t是一个字典,共有六个字符串key(year,month,day,hour,minute,second),值为每个值为数字组成的字符串, 如t={‘year’:‘2013’,‘month’:‘9’,‘day’:‘30’,‘hour’:‘16’,‘minute’:‘45’,‘second’:‘2’} 请将其按照以下格式输出, 格式:XXXX-XX-XX XX:XX:XX。如上例应该输出: 2013-09-30 16:45:02。

利用datetime库

import datetime
print(datetime.datetime(**{k:int(t[k]) for k in t.keys()}).strftime("%Y-%m-%d %H:%M:%S"))

26.给你一个整数组成的列表L,按照下列条件输出: 若L是升序排列的,则输出"UP"; 若L是降序排列的,则输出"DOWN"; 若L无序,则输出"WRONG"。

m1,m2 = L.copy(),L.copy()
m1.sort()
m2.sort(reverse = True)
if m1 == L:print('UP')
elif L == m2:print('DOWN')
else:print('WRONG')

27.一个环形的公路上有n个加油站,编号为0,1,2,…n-1, 每个加油站加油都有一个上限,保存在列表limit中,即limit[i]为第i个加油站加油的上限, 而从第i个加油站开车开到第(i+1)%n个加油站需要cost[i]升油,cost为一个列表。 现在有一辆开始时没有油的车,要从一个加油站出发绕这个公路跑一圈回到起点。 给你整数n,列表limit和列表cost,你来判断能否完成任务。 如果能够完成任务,输出起始的加油站编号,如果有多个,输出编号最小的。 如果不能完成任务,输出-1。

gas_station = []  # 能完成任务的加油站编号列表
for i in range(n):  # 从第0个加油站作为起点开始算gas_total = 0  # 汽车的油量station_num = 0  # 经过加油站的个数for j in range(i,n+i):if j >=n:j = j-ngas_total += limit[j] # 加油if gas_total >= cost[j]:station_num +=1gas_total = gas_total-cost[j]else:break # 不够就直接跳出了if station_num == n:gas_station.append(i)if gas_station != []:print(min(gas_station))
else:print(-1)

28.给你一个整数列表L,判断L中是否存在相同的数字, 若存在,输出YES,否则输出NO。

flag = 0
for i in range(len(L)):for j in range(i+1,len(L)):if L[i] == L[j]:flag = 1breakif flag:print('YES')
else :print('NO')

29.给你三个整数a,b,c, 判断能否以它们为三个边长构成三角形。 若能,输出YES,否则输出NO。

list = [a,b,c]
list.sort()
if list[0] + list[1] >list[2]:print('YES')
else:print('NO')

30.一道水题哈哈哈就不给了

31.十一假期,小P出去爬山,爬山的过程中每隔10米他都会记录当前点的海拔高度(以一个浮点数表示), 这些值序列保存在一个由浮点数组成的列表h中。回到家中,小P想研究一下自己经过了几个山峰,请你帮他计算一下,输出结果。 例如:h=[0.9,1.2,1.22,1.1,1.6,0.99], 将这些高度顺序连线,会发现有两个山峰,故输出一个2(序列两端不算山峰)

h_jian=[]
for i in range(len(h)-1):h_jian.append(h[i+1]-h[i])
sum = 0
for i in range(len(h_jian)-1):if h_jian[i] > 0 and h_jian[i + 1] <0:sum += 1
print(sum)

32.给以一个三角形的三边长a,b和c(边长是浮点数),请你判断三角形的形状。 若是锐角三角形,输出R, 若是直角三角形,输出Z, 若是钝角三角形,输出D, 若三边长不能构成三角形,输出W.

list1 = [a,b,c]
list1.sort()
a = list1[0];b = list1[1];c = list1[2];
if a + b < c:print('W')
elif (a*a+b*b-c*c)/2*a*b == 0 :print('Z')
elif (a*a+b*b-c*c)/2*a*b < 0:print('D')
else :print('R')

33.给你两个正整数a(0 < a < 100000)和n(0 <= n <=100000000000),计算(a^n) % 20132013并输出结果

直接a**n%20132013的话时间复杂度太高了,用pow函数

print(pow(a,n,20132013))

34.生活在当代社会,我们要记住很多密码,银行卡,qq,人人,微博,邮箱等等。小P经过一番思索之后,发明了下面这种生成密码方法:给定两个正整数a和b, 利用a / b我们会得到一个长度无限的小数(若a / b不是无限小数,比如1/2=0.5,我们认为0.5是0.5000000…,同样将其看做无限长的小数),小P将该小数点后第x位到第y位的数字当做密码,这样,无论密码有多长,小P只要记住a,b,x,y四个数字就可以了,牢记密码再也不是那么困难的事情了。现在告诉你a,b,x,y(0 < a,b <= 20132013, 0 < x <= y < 100000000000),请你输出密码。例如:a = 1, b = 2, x = 1, y = 4, 则 a / b = 0.5000000…, 输出小数点后第1到4位数字,即5000

首先有个余数定理,(ab)%c=(a%c)(b%c)%c,其实比较好理解的是(ab)%c=(a%c)(b%c),这就一分配律,这个式子对于很多数字都是成立的,但是也有特殊情况,比如,23,19除以5的余数分别是3和4,但2319对5取余不是12啊,还得再做一次取余,即(ab)%c=(a%c)*(b%c)%c。

转化一下,a/b的小数点后第x到y位,将结果的小数点后移(x-1)位,即为小数点后第1位到(y-x+1)位
也就是关注(a10^(x-1))/b的小数点后的结果,忽略小数点前的结果,即对b取余后的结果除以b的结果
(a
10^(x-1))%b = ((a%b)*(10^(x-1)%b))%b,这个数字肯定小于b

想想,如果40 /26,你想拿到小数点后的第一位,是不是要40%26后,乘以10 = 140,然后140再//26, 你想想你做除法的时候是怎么做的。想想除法的过程

r=''
a = (a%b*pow(10,x-1,b))%b
for i in range(x,y+1):a = (a % b) *10r += str(a // b)
print(r)

35 .给你一个整数list L, 如 L=[2,-3,3,50], 求L的一个连续子序列,使其和最大,输出最大子序列的和。 例如,对于L=[2,-3,3,50], 输出53(分析:很明显,该列表最大连续子序列为[3,50]).

max = L[0]
for i in range(len(L)+1):for j in range(i,len(L)+1):s = sum(L[i:j])if s > max:max = s
print(max)

36.给你一个整数list L, 如 L=[2,-3,3,50], 求L的一个非连续子序列,使其和最大,输出最大子序列的和。 这里非连续子序列的定义是,子序列中任意相邻的两个数在原序列里都不相邻。 例如,对于L=[2,-3,3,50], 输出52(分析:很明显,该列表最大非连续子序列为[2,50]).

# L_max用来存放L数组中对应位置前N项中的最大子序列的和
L_max = [0] * len(L)
if len(L) <= 2:print(max(L))
else:L_max[0] = L[0]L_max[1] = max(L[0], L[1])for i in range(2, len(L)):# 对L_max[i]的赋值为,以下三项中最大的一项:L_max[i - 1], L[i] + L_max[i - 2], L[i]L_max[i] = max(L_max[i - 1], L[i] + L_max[i - 2], L[i])print(L_max[-1])

37.给你直角三角形的两个直角边的边长a,b,请你求出其斜边边长,结果保留小数点后三位小数。 如a=3, b =4, 则输出5.000。

import math
res = math.sqrt(a**2+b**2)
print('%.3f'%res)

38.给你一个字符串列表L,请用一行代码将列表所有元素拼接成一个字符串并输出。 如L=[‘abc’,‘d’,‘efg’], 则输出abcdefg。

print(''.join(L))

39.给你一个字符串列表L,用一行代码顺序输出L中的元素,元素之间以一个空格隔开,注意行尾不要有空格,输出单独占一行。 如L=[‘abc’,‘d’,‘efg’], 则输出abc d efg。

print(' '.join(L))

40.给你两个整数a和b(-10000<a,b<10000),请你判断是否存在两个整数,他们的和为a,乘积为b。若存在,输出Yes,否则输出No

例如:a=9,b=15, 此时不存在两个整数满足上述条件,所以应该输出No。

flag = "No"
if b == 0:flag = "yes"
else:for x in range(-10000, abs(a)+1): #x最大值不会超过a的绝对值if b == x * (a - x):flag = "Yes"break
print(flag)

41.Py从小喜欢奇特的东西,而且天生对数字特别敏感,一次偶然的机会,他发现了一个有趣的四位数2992, 这个数,它的十进制数表示,其四位数字之和为2+9+9+2=22,它的十六进制数BB0,其四位数字之和也为22, 同时它的十二进制数表示1894,其四位数字之和也为22,啊哈,真是巧啊。 Py非常喜欢这种四位数,由于他的发现,所以这里我们命名其为Py数。 现在给你一个十进制4位数n,你来判断n是不是Py数,若是,则输出Yes,否则输出No。 如n=2992,则输出Yes; n = 9999,则输出No。

def f(n,m):a=[]while(n):a.append(int(n%m))n = n//mreturn an_16 = f(n,16)
n_12 = f(n,12)n = str(n)
sum1 = 0
for i in n:sum1 += int(i)if sum1 == sum(n_16) == sum(n_12):print('Yes')
else :print('No')

42.把一个偶数拆成两个不同素数的和,有几种拆法呢? 现在来考虑考虑这个问题,给你一个不超过10000的正的偶数n, 计算将该数拆成两个不同的素数之和的方法数,并输出。 如n=10,可以拆成3+7,只有这一种方法,因此输出1.

sushu=[]
for i in range(2,10001):  # 1不算 从2 开始for j in range(2,int(i/2)):   #到i/2就可以,减少时间复杂度if i % j == 0:   #判断是否是素数breakelse :sushu.append(i)
#n = 4
sum1 = 0
for i in sushu:for j in sushu:if n == i+j and i != j:sum1 += 1
print(sum1//2)

43斐波那契数列为1,1,2,3,5,8…。数列从第三项起满足,该项的数是其前面两个数之和。现在给你一个正整数n(n < 10000), 请你求出第n个斐波那契数取模20132013的值(斐波那契数列的编号从1开始)

a=[1,1]
for i in range(2,n):a.append(a[i-2] + a[i-1])
print(a[n-1] %20132013)

44.有一楼梯共n级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第n级,共有多少种走法? 现在给你一个正整数n

第n个台阶走法数等于n-1 和 n-2级的走法数之和

L = [0] * n
L[0],L[1] = 1,1
for i in range(2,n):L[i] = L[i-1] + L[i-2]
print(L[n-1])

45.有一组砝码,重量互不相等,分别为m1、m2、m3……mn;它们可取的最大数量分别为x1、x2、x3……xn。 现要用这些砝码去称物体的重量,问能称出多少种不同的重量。 现在给你两个正整数列表w和n, 列表w中的第i个元素w[i]表示第i个砝码的重量,列表n的第 i个元素n[i]表示砝码i的最大数量。i从0开始,请你输出不同重量的种数。 如:w=[1,2], n=[2,1], 则输出5(分析:共有五种重量:0,1,2,3,4)

#w = [1, 2, 3];n = [12, 5, 8]
w_count = []
for i in range(len(w)):for _ in range(n[i]):w_count.append(w[i])  # 先把砝码给展开看
s=[]
for i in range(len(w_count)):a = w_count[i]         if a not in s:s.append(a)for j in range(i+1,len(w_count)):  # 展开后是这样,先看第一个有没有,没有的话就加入,然后看第一个加第二个,第一个+第二个+第三个... 第二个+第三个+...a += w_count[j]if a not in s:s.append(a)
s.append(0) # 0的话每个都可以测的
s.sort()  # 看的舒服一点哈哈
print(len(s))

46.有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法, 一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。 现在给出初始的两堆石子的数目a和b,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。 如果你是胜者,输出Win,否则输出Loose。 例如,a=3,b=1, 则输出Win(你先在a中取一个,此时a=2,b=1,此时无论对方怎么取,你都能将所有石子都拿走).

威佐夫博弈,套入公式定理,会用就行了

n = abs(a - b)
m = min(a, b)
if m == int(n*(pow(5, 0.5)+1)//2):print('Loose')
else:print('Win')

47.还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 … 先在给你一个正整数n,请你输出杨辉三角的前n层 注意:层数从1开始计数,每层数字之间用一个空格隔开,行尾不要有空格。 如n=2,则输出: 1 1 1

m=[]
for i in range(n):m.append([])for j in range(i+1):m[i].append(0)  # 先给他一个数if j == 0 or j == i :m[i][j] = str(1)else:temp = int(m[i-1][j-1]) + int(m[i-1][j])m[i][j] = str(temp)for i in range(len(m)):for j in range(len(m[i])):if j == len(m[i]) -1:print(m[i][j])else:print(m[i][j],end = ' ')

48.有一组砝码,重量互不相等,分别为m1、m2、m3……mn;每种砝码的数量有无限个。 现要用这些砝码去称物体的重量,给你一个重量n,请你判断有给定的砝码能否称出重量n。 现在给你一个正整数列表w和一个正整数n,列表w中的第i个元素w[i]表示第i种砝码的重量, n表示要你判断的重量。如果给定砝码能称出重量n,输出Yes,否则输出No。 例如,w=[2,5,11], n=9,则输出Yes(取两个2,一个5)。

w.sort()
w = w[::-1]
for i in range(len(w)):n = n % w[i]if n == 0:print('Yes')break
else:print('No')

49.给你一个十进制数a,将它转换成b进制数,如果b>10,用大写字母表示(10用A表示,等等) a为32位整数,2 <= b <= 16 如a=3,b = 2, 则输出11

a = 31;b = 16
def f(n,m):a=[]while(n):a.append(int(n%m))n = n//mreturn a
def zh(a,b):list1 = f(a,b)s = ''l = ['A','B','C','D','E','F']for i in list1:if i < 10:s += str(i)else:s += l[i-10]return s[::-1]if a > 0:print(zh(a,b))
elif a == 0:print(0)
else :print('-' + zh(-a,b))

50.Py不但是编程大牛,而且是运动健将。比如说扔铅球,1000m,现在Py参加校园扔铅球比赛, 给你Py的身高a(双精度数),球落地点与Py头部的连线与水平线的夹角 b(弧度), 要你编写一个程序计算Py扔铅球的水平距离。 a,b都是浮点数,注意b是弧度,其中, 140 < a < 200, 0 < b < 1.5. 输出你求出的水平距离,保留到小数点后三位。 如,a = 165.5, b=1.1, 则输出84.234

import math
c = a / (math.tan(b))
print('%.3f' % c)

51.给你一个list L, 如 L=[2,8,3,50], 对L进行降序排序并输出, 如样例L的结果为[50,8,3,2]

print(sorted(L,reverse = True))

52. 6 的因子有 1, 2, 3 和 6, 它们的平方和是 1 + 4 + 9 + 36 = 50. 如果 f(N) 代表正整数 N 所有因子的平方和, 那么 f(6) = 50. 现在令 F 代表 f 的求和函数, 亦即 F(N) = f(1) + f(2) + … + f(N), 显然 F 一开始的 6 个值是: 1, 6, 16, 37, 63 和 113. 那么对于任意给定的整数 N (1 <= N <= 10^8), 输出 F(N) 的值.

这题最重要的就是要考虑到时间复杂度的问题,正常来说像这样是最常规的

def f(n):list1 = []for i in range(1,n+1):if n % i == 0:list1.append(i)sum = 0for i in range(len(list1)):sum += list1[i]**2return sumdef F(n):sum = 0for i in range(1,n+1):sum += f(i)return sumprint(F(6))

但时间复杂度是n^2,太高了,想办法降下来

考虑到首先思路当n=100的时候,1的倍数有100个,所以1是这100个数的因子,所以要平方100次,2的倍数是100/2=50个,以此类推,直到50的倍数有 两个,50以上全部都是一个
想想那如果不算100的话,是不是50的平方只要加一次,其他的类推

s = (N * (N + 1) * (2*N + 1)) // 6
ls = ( i * i * (N // i - 1) for i in range(1, N//2+1))
s += sum(ls)
print(s)

53.如果我们定义 (n, m) 是一个安排(其中 1 < m < n), 而如果 C(m,2)/C(n,2) = 1/2, 它就是神的安排. 现在的问题是, 给你一个不大于 10^9 的正整数 N, 有多少组神的安排 (n, m) 满足 n <= N 呢?

佩尔方程

'''
根据题意列出方程 2*m^2-2*m=n^2-n,转换为佩尔方程形式:
(2*n-1)^2-2*(2*m-1)^2=-1。
记x=2n-1,y=2m-1,原方程即为:x^2-2*y^2=-1
先计算x^2-2*y^2=1的基本解,(3,2)为基本解,
得到 x,y的迭代公式:
x=3x0+4y0,y=2x0+3y0
最小的(x0,y0)为(1,1),要求n>m>1,且n和m需要为整数
分析发现x和y一直为奇数,所以不再需要判断n和m是否为整数
'''
x = 1
y = 1
c = -1  # 计数,初始值设为-1,N=1时,(x,y)=(1,1),c=0
while x <= 2 * N - 1:c += 1x, y = 3 * x + 4 * y, 2 * x + 3 * y
print(c)

54.记得一副有趣的对联: “雾锁山头山锁雾, 天连水尾水连天”, 上联和下联都是回文的. 当然类似的还有: “上海自来水水来自海上, 山西悬空寺寺空悬西山”. 回文是什么意思? 就是把内容反过来读也是和原来一样的, 譬如 abccba, xyzyx, 这些都是回文的. 然而我们更感兴趣的是在一个英文字符串 L 中, 怎么找出最长的回文子串. 例如 L = “caayyhheehhbbbhhjhhyyaac”, 那么它最长的回文子串是 “hhbbbhh”. 这个任务看似简单, 但是如果我告诉你 L 的长度可能会接近 10^4, 问题似乎就变麻烦了. 不管怎么说, 加油吧骚年.

manacher算法

def init1(s):S = "^#"for i in range(0,len(s)):S = S + s[i] + "#"S = S + "$"return S    # 前后加两个不同的符号是为了后面判断while的时候超出范围def solution(s):s = init1(s)P = [0 for i in range(0,len(s))]M=0;R=0for i in range(1,len(s)-1):j = M*2 - iif R > i:if R - i > P[j]:P[i] = P[j]else :P[i] = R - ielse :P[i] = 0while s[i + P[i] + 1] == s[i - P[i] -1]:P[i] = P[i] + 1if i + P[i] > R:R = i + P[i]M = iCenter = 0maxl = 0for i in range(1,len(s)-1):if P[i] >= maxl:maxl = P[i]Center = istart = Center - maxl+1end = Center + maxlreturn s[start:end:2]print(solution(L))

57.不知道大家的童年有没有过和我相似的经历。我记得小时候经常买干脆面,不为别的,只是因为里面有一张人物卡片。 其实有很多这样的活动都有一个相同的模式:N 种人物卡片,每次买一包干脆面随机得到一张。当你集齐这 N 种人物时,就会有相应的奖励。 那时候还不懂怎么计算概率,白白给人家送了好多钱,吃了好多干脆面。 现在的任务是,给你一个正整数 N (1 <= N <= 10^4),请你帮我从期望的角度计算平均需要买多少包干脆面才能集齐这 N 种人物。 提醒:由于结果可能不是整数,所以结果只保留到小数点后两位。

1种卡片,怎么买都可以买到,期望就是 1
2种卡片,拿到第1种以后,拿到第2种的概率就是 1/2, 理论上还需要买2包。期望和 = 3/3 + 2/1
3种卡片, 拿到第1种以后,拿到第2种的概率就是2/3, 理论上需要买 3/2 包,再拿到第3种的概率就是 1/3 ,理论上需要买 3/1 包。 期望和 = 3/3 + 3/2 + 3/1

sum = 0
for i in range(1,N+1):sum += N/i
print('%.2f'% sum)

58.小Py要吃西瓜,想知道切了n刀后,最多能切出多少块?请你们帮助下小Py. 给你一个正整数n(0 < n < 10^3),你输出一个数字,代表最多能切多少块。 如n=1, 输出2。

这个问题的本质是n个平面最多可以把空间划分成多少块.我们来看如下三个问题:

  1. n个点最多可以把一条直线划分成多少段,通项公式记为A(n)。 2) n条直线最多可以把平面划分多成个区域,通项公式记为B(n)。 3) n个平面最多可以把空间划分多少块,通项公式记为C(n)。

第一个问题,很简单,A(n) = n+1

第二个问题,假设平面上已有n条直线它们把平面划分成最多的区域,那么第n+1条直线下去的时候,为了保证获得最多的区域,那么要求这条直线和之前的n条直线都相交,并且新产生的交点不和之前的交点重合.显然第n+1条直线和之前的n条直线产生n个交点,这n个交点把第n+1条直线划分成A(n)段,每一段都将原来的区域一分为二,于是B(n + 1) = B(n) + A(n),将B(1) = 2,A(n) = n + 1带入很容易求得B(n) = [n(n + 1) / 2] + 1

第三个问题,同理考察第n+1个平面下去多增加了多少块.前面的n个平面都和第n+1个平面相交,在第n+1个平面上留下n条交线,这n条交线最多将第n+1个平面划分成B(n)个区域,每个区域都将原来的块一分为二,于是C(n+1) = C(n) + B(n),将C(1) = 2,B(n) = [n(n + 1) / 2] + 1带入可以求得C(n) = [(n^3 + 5n) / 6] + 1

print(int((n**3+5*n+6)/6))

59.M个人围成一圈,每分钟相邻的两个人可以交换位置(只能有一对交换)。 现在给你一个正整数n(0 < n < 1000),求使n个人的顺序颠倒(即每个人左边相邻的人换到右边,右边相邻的人换到左边)所需的最少时间(分钟数)。 如:n=4, 输出2.

根据奇偶来一分为二,因为这是成环的,不需要把 12345 转化成 54321, 变成 32154 就可以了。
然后再讨论一下,把一个数组倒过来,需要多少步,这实际上还是很好算的。自己可以推导一下。
我给一个 递推公式: f[n] = f[n-1] + n-1

nums = [0, 0, 1, 3]for i in range(4, 1000):nums.append(nums[i-1] + i-1)print(nums[n//2]+nums[n//2] if n % 2 == 0 else nums[n//2] + nums[n//2+1])

60.给你一个正整数list L, 如 L=[2,8,3,50], 求列表中所有数的最小公倍数(不用考虑溢出问题)。 如L=[3,5,10], 则输出30

最大公约数*最小公倍数 = 两个数的乘积

from math import gcd
ans = 1
for num in L:gc = gcd(ans, num)ans = (ans * num) // gcprint(ans)

61.现在有一堆木棒,告诉你它们的长度,判断能否用这些木棒拼接成正方形。 注意:所有的木棒都要用上,且不能截断。 给你一个正整数list L, 如 L=[1,1,1,1], L中的每个数字代表一个木棒的长度,如果这些 木棒能够拼成一个正方形,输出Yes,否则输出No。 如L=[1,1,1,1],则输出Yes;L=[1,1,1],则输出No。 注:数据已于2014-03-11加强,之前通过的代码可能无法再次通过

如果木棒总长度不是4的倍数,那么肯定不能组合成一个正方形。
如果我们用排列组合的方式,那就相当于是 4^n 次方,肯定超时,就不多想了。
然后我再想,先一分为二,再一分为二。 初步估计了一下时间复杂度,放弃了。
正确的办法:

  • 将所有木棒根据长度从大到小排序。
  • 得到所有木棒的长度总和,判断能否构成四边形以及四边的长度。
  • 再依次将木棒放到四边剩余长度最大的边。
  • 循环操作第3步,直到所有木棒全部放入四边。
  • 最后判断四边是否全部为0。

虽然不知道为啥可以这样,但是代码通过了。我还是给出我的一个思考,感觉没啥问题。
假设我们现在手里拿了 1 根木棒,并且只能放入剩余长度最大的边,其他边放不下这根木棍,那就只能放入剩余长度最大的边了。
如果有 n 个边都可以放,并且这 n 个边剩余长度都一样,那就随便放1个边都可以。
如果现在有 n 个边都可以放,但是 n 个边的 剩余长度都不一样,怎么办?
假设现在有木棒 a > b。 2个边 分别为 A>B。
把 a 放入 A 中,那么A就变成了 A-a。
把 a 放入 B 中,那么B就变成了 B-a
因为 A>B, 所以 A-a > B-a 。
那么 b < A-a 的可能就比 b < B-a 的可能要高,这样我们就可以把更多的木棒加入4边中。
而我们的目的就是尽可能的把所以木棒放入到4个边中。

sum_L = sum(L)
if sum_L%4  or not sum_L:print("No")
else:lst = [sum_L//4 for i in range(4)]L.sort()while L:        lst[3] -= L.pop()lst.sort()if not min(lst):print("Yes")else:print("No")

62.给你两个整数a和b(0 < a,b < 1000),按笔算的格式输出a乘以b(a是被乘数,b是乘数)的运算过程, 最后再输出一行 “********************”(二十个星号)。 乘号用小写字母“x”表示,每行末尾不能有多余的空格

def solve_it(a,b):print('%8d' % a)print('x%7d' % b)print('--------')if b//100:print('%8d' % (a * (b % 100)))print('%7d' % (a * (b // 10%10))+' ')print('%6d'% (a * (b // 100))+'  ' )elif b//10:print('%8d' % (a * (b % 10)))print('%7d' % (a * (b // 10)) + ' ')else:print('%8d' % (a * b ))print('*' * 20)returnprint('--------')print('%8d'%(a*b))print('*' * 20)
solve_it(a,b)

63.桌子上有一堆数量不超过20的果子,每个果子的重量都是不超过20的正整数,全部记录在列表 L 里面。小明和小红决定平分它们,但是由于他们都太自私,没有人愿意对方比自己分得的总重量更多。而果子又不能切开,所以最后他们商量好的平分方案是这样的:他们可以把某些果子扔掉,再将剩下的果子平分,请你求出在这种方案下他们每人最多可以分得的糖果重量。

贪心算法,但是贪心算法只能适用于大多数情况,会有少数情况得不到最优解

def solve_it(l):# 排序l.sort()# 当最大值大于和的一半,则去除最大元素while l[-1] > sum(l) / 2:l.remove(l[-1])if len(l) >= 3:continue# 当列表长度小于3就作个判断即可解决问题else:return l[0] if len(l) == 2 and l[0] == l[1] else 0# 将处理好的新列表拷贝,为后面贪心算法做准备L = l.copy()# 若列表和为奇数,则去除一个最小奇数,使和为偶数进行平分if sum(l) % 2 != 0:for i in l:if i % 2 != 0:l.remove(i)break# 记录列表和的一半,并把最大值赋给临时变量side = sum(l) // 2tmp = l.pop()# 循环查找 side - tmp 是否在列表里for i in range(len(l)):# 找到,则返回sideif side - tmp in l[i+1:] or side - tmp == 0:return side# 找不到,贪心算法,去除一个最小值,递归调用elif tmp + l[i] > side:return solve_it(L[1:])# 循环找else:tmp += l[i]
print(solve_it(L))

64.互联网上的每台计算机都有一个IP,合法的IP格式为:A.B.C.D。 其中A、B、C、D均为位于[0, 255]中的整数。为了简单起见,我们规定这四个整数中不允许有前导零存在,如001这种情况。 现在给你一个字符串s(s不含空白符),请你判断s是不是合法IP,若是,输出Yes,否则输出No. 如:s=“202.115.32.24”, 则输出Yes; s=“a.11.11.11”, 则输出No.

import re
if re.findall('[1-2]?\d?\d\.[1-2]?\d?\d\.[1-2]?\d?\d\.[1-2]?\d?\d', s) == [s]:  #? 是出现一次或者0次print('Yes')
else:print('No')

65.在RSA密码体系中,欧几里得算法是加密或解密运算的重要组成部分。它的基本运算过程就是解 (x*a) % n = 1 这种方程。 其中,x,a,n皆为正整数。现在给你a和n的值(1 < a,n < 140000000),请你求出最小的满足方程的正整数解x(保证有解). 如:a = 1001, n = 3837,则输出23。

由公式我们可以 知道(x*a) % n = 1,也就是说((x%n) * (a%n)) % n = 1,还有主要的x a = kn + 1,而我们的任务就是去找k的值,到这里就不难了,就是用循环的方式去找k;

但是有一个要注意的就是a的值,如果直接使用的话,会导致超时,由于我们推出的第一个公式,我们可以用a = a % n
a = a % n
k = 0
while True:
if (kn+1) % a == 0:
print(int((k
n+1)/a))
break
else:
k += 1

67.什么叫自复制数呢?我们看看下面的例子: 625×625=390625 376×376=141376 9376×9376=87909376 90625×90625=8212890625 如果一个数的平方末尾还是这个数本身,那么它就是自复制数。 现在告诉你长度为101位的自复制数只有一个,你能把它找出来吗?请输出这个101位的自复制数。

a=7109376for i in range(8,102):a=str(int(a)**5)[-i:]#print(a)if len(str(a))==101:print(a)

规律是一个n位的自复制数的五次方的负n+1位是新的自复制数的第一位,比如5**5=3125,25也是一个自复制数

68.N的阶乘定义为:N!=N×(N-1)×……×2×1 请编写一个程序,输出N的阶乘的十进制表示中从最末一个非0位开始自低位向高位数的第K位。 现在给你N和K(0<=N<=10000,1<=K<=5),请你输出要求的数字(保证存在)。 例如:N=5,K=2,则输出1 note:(5!=120); N=8,K=3,结果为0 note:(8!=40320)

import math
#N = 777
#K=5
y = math.factorial(N)
while y % 10 == 0:y = y//10
print(str(y)[-K])

69.若一个数(首位不为0)从左到右读与从右到左读都是一样,这个数就叫做回文数,例如12521就是一个回文数。 给定一个正整数,把它的每一个位上的数字倒过来排列组成一个新数,然后与原数相加,如果是回文数则停止,如果不是,则重复这个操作,直到和为回文数为止。给定的数本身不为回文数。 例如:87则有: STEP1: 87+78=165 STEP2: 165+561=726 STEP3: 726+627=1353 STEP4: 1353+3531=4884 现在给你一个正整数M(12 <= M <= 100),输出最少经过几步可以得到回文数。如果在8步以内(含8步)不可能得到回文数,则输出0。 例如:M=87,则输出4.

def is_huiwen(x):if str(x) == str(x)[::-1]:return 1else:return 0
def jiadaoshu(x):return x+int(str(x)[::-1])#M = 87
count = 0
while not is_huiwen(M):M = jiadaoshu(M)count +=1
if count > 8 :print(0)
else:print(count)

70.设有n个正整数,将他们连接成一排,组成一个最大的多位整数. 例如:3个整数13,312,343,连成的最大整数为:34331213 又如:4个整数7,13,4,246连接成的最大整数为7424613 现在给你一个正整数列表L,请你输出用这些正整数能够拼接成的最大整数。 note:测试数据已于2014年11月13日更新,以前通过的代码不一定能够再次通过。

Python cmp_to_key用法,排序的规则不单单是数的大小了

from functools import cmp_to_key
L = list(map(str, L))
def cmp_decline(x, y):if int(x + y) < int(y + x):return 1else:return -1
L.sort(key=cmp_to_key(cmp_decline))
print(''.join(L))

71.又是回文数!但这次有所不同了。 给定一个N进制正整数,把它的各位数字上数字倒过来排列组成一个新数,然后与原数相加,如果是回文数则停止,如果不是,则重复这个操作,直到和为回文数为止。 如果N超过10,使用英文字母来表示那些大于9的数码。例如对16进制数来说,用A表示10,用B表示11,用C表示12,用D表示13,用E表示14,用F表示15。 例如:10进制87则有: STEP1: 87+78=165 STEP2: 165+561=726 STEP3: 726+627=1353 STEP4: 1353+3531=4884 给你一个正整数N(2<=N<=16)和字符串M(“1”<=M<=“30000”(10进制)),表示M是N进制数,输出最少经过几步可以得到回文数。 如果在30步以内(含30步)不可能得到回文数,则输出0。输入的数保证不为回文数。 如N=10, M=“87”, 则输出4.注意:M是以字符串的形式给定的。

def ten_to_N(N,M):M = int(M)res = ''d = {10:'A',11:'B',12:'C',13:'D',14:'E',15:'F'}while M:temp = M % Nif temp in d:temp = d[temp]res += str(temp)M = M//Nreturn res#N进制转化为10进制
def N_to_ten(N,M):res = 0d = {'A':10,'B':11,'C':12,'D':13,'E':14,'F':15}count = len(M) - 1for each in M:if each in d:each = d[each]res += pow(N,count) * int(each)count -= 1return res
#回文数
def Hui(n):t = str(n)if t == t[::-1]:return 1return 0count = 30      #最多30次
flag = 0
while count:if Hui(M):  #如果是回文数,标志flag = 1flag = 1breakelse:temp = Msum1 = N_to_ten(N,M)    #本身转化为10进制sum2 = N_to_ten(N,M[::-1])  #倒过来的数转化为10进制M = ten_to_N(N,str(sum1 + sum2)) #10进制相加后转回N进制count -= 1      #次数减一
print(30 - count) if flag else print(0)

72.球赛门票的售票处规定每位购票者限购一张门票,且每张门票售价50元。购票者中有m位手持50元钱币,另有n人手持100元。假设售票处开始售票时无零钱。问这m+n人有几种排队方式可使售票处不致出现找不出钱的局面。 对给定的m,n(0<=m,n<=5000),计算出排队方式总数。

def solve_it(m,n):if n > m:return 0else:row = [1 for _ in range(m)]column = [0 for _ in range(n)]# 不断进行值的覆盖for i in range(n):for j in range(i,m):row[j] += column[i]column[i] = row[j]# print(row, column)return row[-1]
print(solve_it(m,n))

73.给你一个数 n (1 < n <= 1000000) ,求 n! (n的阶乘)的质因数分解形式. 质因数分解形式为: n=p1m1*p2m2p3^m3…… * 这里 p1 < p2 < p3 < …… 为质数 * 如果 mi = 1, 则 ^ mi 就不需要输出 如:n=6,则输出:6=24*325 n=7,则输出:7=24*3257

def isPrime(value):up = int(value ** 0.5) + 1for i in range(2, up):if i != value and value % i == 0:return Falsereturn Truedef Primes(n):rsl = []for i in range(2, n+1):if isPrime(i):rsl.append(i)return rsl#n = 6
PrimesList =  Primes(n)
numList = [0] * len(PrimesList)
for i in range(2, n+1):for index in range(len(PrimesList)):value = iwhile value % PrimesList[index] == 0:numList[index] = numList[index] + 1value = value / PrimesList[index]if value == 1:break
#print PrimesList
#print numList
rsl = str(n) + '='
for i in range(len(PrimesList)):if numList[i] > 0:rsl += str(PrimesList[i])if numList[i] != 1:rsl += '^' + str(numList[i])rsl += '*'
print (rsl[:-1])

74.求组合数 C ( n , k) 的奇偶性. 给你n和k(1<=n<=10^9,0<=k<=n),若其为奇数,则输出1,否则输出0. 如n=2,k=0,则输出1. 因为C(2,0)=1,为奇数。

res = 0
if k == 0 or n == k:res = 1
else:nn = 0while n:nn += (n // 2)n //= 2nk = 0while k:nk += (k // 2)k //= 2if nn > nk:res = 0else:res = 1
print(res)持续更新

Pythontip刷题记录相关推荐

  1. LeetCode刷题记录15——21. Merge Two Sorted Lists(easy)

    LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) 目录 LeetCode刷题记录15--21. Merge Two Sorted Lists(easy) ...

  2. LeetCode刷题记录14——257. Binary Tree Paths(easy)

    LeetCode刷题记录14--257. Binary Tree Paths(easy) 目录 前言 题目 语言 思路 源码 后记 前言 数据结构感觉理论简单,实践起来很困难. 题目 给定一个二叉树, ...

  3. LeetCode刷题记录13——705. Design HashSet(easy)

    LeetCode刷题记录13--705. Design HashSet(easy) 目录 LeetCode刷题记录13--705. Design HashSet(easy) 前言 题目 语言 思路 源 ...

  4. LeetCode刷题记录12——232. Implement Queue using Stacks(easy)

    LeetCode刷题记录12--232. Implement Queue using Stacks(easy) 目录 LeetCode刷题记录12--232. Implement Queue usin ...

  5. LeetCode刷题记录11——290. Word Pattern(easy)

    LeetCode刷题记录11--290. Word Pattern(easy) 目录 LeetCode刷题记录11--290. Word Pattern(easy) 题目 语言 思路 源码 后记 题目 ...

  6. LeetCode刷题记录10——434. Number of Segments in a String(easy)

    LeetCode刷题记录10--434. Number of Segments in a String(easy) 目录 LeetCode刷题记录9--434. Number of Segments ...

  7. LeetCode刷题记录9——58. Length of Last Word(easy)

    LeetCode刷题记录9--58. Length of Last Word(easy) 目录 LeetCode刷题记录9--58. Length of Last Word(easy) 题目 语言 思 ...

  8. LeetCode刷题记录8——605. Can Place Flowers(easy)

    LeetCode刷题记录8--605. Can Place Flowers(easy) 目录 LeetCode刷题记录8--605. Can Place Flowers(easy) 题目 语言 思路 ...

  9. LeetCode刷题记录7——824. Goat Latin(easy)

    LeetCode刷题记录7--824. Goat Latin(easy) 目录 LeetCode刷题记录7--824. Goat Latin(easy) 题目 语言 思路 后记 题目 题目需要将一个输 ...

最新文章

  1. WebX5 button tabs的bind-text属性设置
  2. 利用源代码搭建lnmp环境
  3. settype COM_LOCAT_ADDR出现在CRM change document里的原因
  4. 彻底理解链接器:二,符号决议
  5. linux服务器组件有哪些,推荐几个linux服务器面板
  6. Spark Streaming 反压机制
  7. 预编译stdafx.h,无法找到文件问题,红色波浪线
  8. [转]求职面试-与女大学生网络对话(上)
  9. cadz轴归零命令_cadz轴归零(cad全部z轴归零)
  10. App自动绑定的五大应用场景
  11. python adf检验_ADF检验结果怎么看?
  12. Tensorrt笔记(七)Tensorrt使用问题整理
  13. swagger2报错Illegal DefaultValue null for parameter type integer
  14. CSS基础学习六:id选择器
  15. java的jsf是什么_什么是 JSF(Java Server Faces)
  16. chainWebpack配置WebWorkers
  17. swap未禁用导致的k8s NotReady
  18. 第二章 高级语言及其语法描述
  19. 2019中国MCN行业发展白皮书
  20. matlab探查器作用,探查器如何捕获性能数据

热门文章

  1. 国内外的一些安全网站收集
  2. 如何查看局域网的其他计算机,怎么查看局域网中其他电脑的信息
  3. Python: email-validator验证Email地址
  4. php java bridge 安装_php-java-bridge扩展安装
  5. [computer vision] Bag of Visual Word (BOW)
  6. 微信小程序毕业设计论文管理系统+后台管理系统项目源代码
  7. 用 Jester 对测试进行测试
  8. html抽奖怎么重置,js实现抽奖的两种方法
  9. 物理隔离网闸——入门篇(1)
  10. python点击屏幕坐标_通过Python,如何获取鼠标在屏幕上的X、Y轴坐标点