一、回文数
1、判断是否是回文数
*思路:
- 对称字符比较
- x[i]取到某个下标的字符
- 遍历时range取0~len(str)
#若是回文数则返回1,否则返回0
def reverse(x):
#x=0则是回文数
if x == 0:
return 1
#x<0则按相反数判断是否是回文数
if x < 0:
return reverse(-x)
#x>0则判断
if x > 0:
print(x)
x = str(x)
l = len(x)
sta = 0
end = l - 1
for k in range(l):
if sta <= end:
if x[sta] == x[end]:
sta+=1
end-=1
continue
return 0
return 1
2、求各位数字的和
*思路:字符按下标一个个取到并强转为int类型相加
def sumd(x):
if x < 0:
return -sumd(-x)
if x > 0:
x = str(x)
sums = 0
for k in range(len(x)):
sums += int(x[k])
return sums
二、杨辉三角
1、生成杨辉三角
*思路:
- 第一二行固定,放入一个数组中triangle = [[1], [1, 1]],之后使用triangle.append添加每行
- 每一行的首尾为1
- 行数=个数,第n行需要算n-2个数,对应range(n-1)
# 前两行固定
triangle = [[1], [1, 1]]
# c为行
c = 1
while (1):
c = c + 1
pre = triangle[c - 1] # 取上一行
this = [1] # 定义每行第一个元素
for j in range(c - 1): # 第c行有c个数字,首个定义了是1,最后一个也是1,则还需要计算c-2个元素
y = pre[j] + pre[j + 1]
if y == x:
return count
# 第0个=0+1;第1个等于1+2
this.append(y) # 每个数字等于上一行的左右两个数字之和。
this.append(1) # 添加每行最后一个元素
triangle.append(this) # 把该行添加到三角里
2、 求杨辉三角第一次出现n是第几个数字:
思路1:只要pre不要triangle,减少内存,但当n很大时运行超时
def adjust():
x = int(input())
if x == 1:
return 1
else:
# 前两行固定
pre = [1, 1]
c=1
count=3
while (1):
c = c + 1
this = [1] # 定义每行第一个元素
count+=1
for j in range(c - 1): # 第c行有c个数字,首个定义了是1,最后一个也是1,则还需要计算c-2个元素
y = pre[j] + pre[j + 1]
count += 1
if y == x:
return count
# 第0个=0+1;第1个等于1+2
this.append(y) # 每个数字等于上一行的左右两个数字之和。
this.append(1) # 添加每行最后一个元素
count += 1
pre=this # 把该行变为pre
if __name__ == '__main__':
n=adjust()
print(n)
思路2:如下图,每条斜线的起始n为2、4、6、8,为c上面数字的两倍,而斜线越靠后找到的数字越早,所以对于一个数字x,找到大于等于某个c(n/2,n),小于下一个c((n+1)/2,n+1)的n,在这一斜线上找,找到大于x但没有等于x时换前一条斜线找,直到找到。
此时的x为第(1+n/2)*n/2/2+n
import math
def adjust():
x=int(input())
if x==1:
return 1
n=0
while(1):
# n为上
n+=1
y=math.factorial(2*n)//(math.factorial(n)*math.factorial(2*n-n))
if y==x:
return (1+2*n)*n+n+1
if y>x:
n=n-1
break
while(n>0):
k=2*n
while(1):
k=k+1
y = math.factorial(k) // (math.factorial(n) * math.factorial(k - n))
if y == x:
return (1+k) * k/2+n+1
if y>x:
n = n - 1
break
if __name__ == '__main__':
n=adjust()
print(int(n))
3、输出杨辉三角前n行
n=int(input())
if n==1:
print(1)
elif n==2:
print(1)
print('1 1')
else:
print(1)
print('1 1')
pre=[1,1]
row=2
while(1):
row+=1
new=[1]
for i in range(row-2):
new.append(pre[i]+pre[i+1])
new.append(1)
for i in range(len(new)):
print(new[i],end=' ')
print()
pre=new
if n==row:
break
三、阶乘计算
输入一个正整数n,输出n!的值。
1、思路:递归,但问题出在递归深度不能超过1000,所以n大小有限制
def fund(x,y):
if x > 1:
y = y * x
y=fund(x-1, y)
return y
if __name__=='__main__':
n = int(input())
y = fund(n, 1)
print(y)
2、思路:循环
n = int(input())
y=1
for i in range(2,n+1):
y=y*i
print(y)
四、树
1、定义
def BinaryTree(r):
return [r, [], []]
r为根节点,后面的第一个[]为r的左子树,第二个[]为r的右子树
五、哈夫曼树
哈夫曼树是一种用于无损数据压缩的熵编码(权编码)算法,变长编码表是通过一种评估符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。——摘自维基百科
对于A,B,C,D,E五个字符出现的出现的频率(即权值)为数列{pi}={5, 3, 8, 2, 9},Huffman树的构造思路为:每次取两个最小权值作为左右子树构造一个新树,最终构成的树如下:
可见C和E权值较高,编码也就较短,若左0右1,则其编码分别为10和11,而权值较低的D和B编码较长,为000和001。
1、求总费用
n=int(input())
p=list(map(int,input().split(' ')))
# print(p)
sum=0
while(len(p)>=2):
min1=min(p)
p.remove(min1)
min2=min(p)
p.remove(min2)
new=min1+min2
p.append(new)
sum+=new
print(sum)
六、拓扑排序
拓扑排序是一个有向无环图的所有顶点的线性序列。且该序列满足下面两个条件:
- 每个顶点出现且只出现一次。
- 若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。
每次去掉入度为0的顶点及其边,一个有向无环图可以有一个或多个拓扑排序序列,如下图的拓扑排序为12435。
参考拓扑排序(Topological Sorting)-CSDN博客
所以,若为有向有环图,将会在最后有一些结点入度均不为0(为1),无法排序。
类比到无向图,若为无向无环图,不分出度入度,统一以度来衡量。从度为1的结点开始遍历,可以完成全部结点的排序,但若为无向有环图,将会在最后有一些结点度均不为1(为2),无法排序。
1、对于题目如下:
N=int(input())
# tree[i]存放结点i的相邻结点
tree=[[]]
# d[i]存放结点i的度
d=[0]
# cun存放所有结点
cun=[]
for i in range(N):
tree.append([])
d.append(0)
cun.append(i+1)
#将每个结点的相邻结点写入
for i in range(N):
a,b=map(int,input().split(' '))
tree[a].append(b)
tree[b].append(a)
d[a]+=1
d[b]+=1
#flag为1结束运行
flag=0
#当还有结点未被去掉
while(len(cun)>0):
flag1=0
#遍历每个结点
for i in range(1,N+1):
#如果该结点的度为1,则去掉该结点,该结点度-1,与该结点相邻的结点度-1并在tree中去掉该删除的结点
if d[i]==1:
flag1=1
cun.remove(i)
d[i]-=1
d[tree[i][0]]-=1
tree[tree[i][0]].remove(i)
continue
#如果本次对剩余结点的遍历发现度全部不为1,则剩下的组成环,输出
if i==N and flag1==0:
for j in range(len(cun)):
print(cun[j],end=' ')
flag=1
if flag==1:
break
七、dfs
dfs是深度优先搜索(Depth-First Search)的缩写,它是一种图遍历算法。该算法从图的某一顶点开始,沿着图的边不断向下探索,直到不能再继续为止,然后回溯到上一个节点,继续探索其他分支。DFS 通常用于解决图和树的遍历问题,以及与搜索连通性有关的问题。
DFS 的递归实现:
题目:输入几个点、几条边,输出删除哪些边可以保证图中没有三角形
class aa():
co_list=[]
def dfs(self,co,i):
now=tree[i-1]
for j in range(len(now)):
if len(co)==3 and now[j]==co[0]:
if len(self.co_list)==0:
self.co_list.append(co)
for n in range(len(self.co_list)):
if set(co)==set(self.co_list[n]):
break
if n==len(self.co_list)-1:
self.co_list.append(co)
if now[j] not in co and len(co)<3:
self.dfs(co+[now[j]],now[j])
a,b=map(int,input().split(' '))
cun=[]
aa=aa()
tree=[]
for i in range(a):
tree.append([])
for i in range(b):
x,y=map(int,input().split(' '))
cun.append([x,y])
tree[x-1].append(y)
tree[y-1].append(x)
# print(tree)
for i in range(a):
co=[i+1]
aa.dfs(co,i+1)
# print(aa.co_list)
if len(aa.co_list)==0:
print(b)
for i in range(b):
print(i+1,end=' ')
if len(aa.co_list)==1:
print(3)
for j in range(len(cun)):
if set(cun[j])<set(aa.co_list[0]):
print(j+1,end=' ')
if len(aa.co_list)==2:
end=set(aa.co_list[0]) & set(aa.co_list[1])
print(1)
for j in range(len(cun)):
if set(cun[j])==end:
print(j+1)
八、质数
zs=[2,3,5,7,11]
for i in range(12,n):
for j in range(len(zs)):
if i%zs[j]==0:
# 有可以除尽的,不是质数
flag=1
break
if flag==0:
zs.append(i)
九、有关日期
闰年:(y % 4 == 0 and y % 100 != 0) or (y % 400 == 0)