Python刷题笔记

Python刷题笔记

1、输出格式化

第一种格式化的输出:

name = "jack"
age = 17
salary = 20031.8752
print("你的名字是:%s,今年 %d 岁,工资 %7.2f" % (name,age,salary) )
---------------------------------------
你的名字是:jack,今年 17,工资 20031.88
---------------------------------------

第二种格式化的输出:

name = "jack"
age = 17
salary = 20031.8752
print(f"你的名字是:{name},今年 {age} 岁,工资:{salary}")
---------------------------------------
你的名字是:jack,今年 17,工资:20031.8752
---------------------------------------

2、数值类型转换

基本格式解释
int(x)将x转换为一个整数
float(x)将x转换为一个浮点数
str(x)将x转换为一个字符串
chr(x)将x转换为一个字符

3、字符串类题型

题型一:大小写转换

1、使用str.lower()方法,把所有大写字母转换成小写字母。

n=input()
print(n.lower())
--------------------
输入:HeLLo WORLD
输出:hello world
--------------------

2、使用str.upper()方法,把所有小写字母转换成大写字母

n=input()
print(n.upper())
--------------------
输入:hello world
输出:HELLO WORLD
--------------------

3、使用str.capitalize()方法,仅首字母转化为大写字母,其余小写字母

n=input()
print(n.capitalize())
--------------------
输入:hello world
输出:Hello world
--------------------

4、使用str.title()方法,每个单词的首字母大写

n=input()
print(n.title())
--------------------
输入:hello world
输出:Hello World
--------------------

题型二:字母(a-z)之间的转换

讲解:ord()表示该字母的ASCII数值【配合ASCII表进行求解

n = int(input())
a=input()
out = ''
for i in range(len(a)):m = ord(a[i]) + nwhile m > ord('z'):m = m - ord('z') + ord('a') - 1out += chr(m)
print(out)
-----------------
输入:
1
qwez
输出:rxfa
-----------------

题型三:反转问题(数字,符号,字母…)

2.1: 全部进行反转操作
a = "Love You"
b = a[::-1]
print(b)
--------------
uoY evoL
--------------
单词倒序问题1

给定一堆用空格隔开的英文单词,输出这些英文单词的倒序(单词内部保持原序)。

比如,输入:Hao Hao Xue Xi,输出:Xi Xue Hao Hao

words = input().split()	# ['Hao', 'Hao', 'Xue', 'Xi']
words.reverse()
# 基本格式:'分隔符'.join(列表【list】)
result = ' '.join(words)print(result)
2.2: 局部进行反转操作
单词倒序问题2

给定一堆用空格隔开的英文单词,将每个单词内部逆序后输出(单词顺序不变)。

比如,输入:Hao Hao Xue Xi,输出:oaH oaH euX iX

a = input().split() # ['Hao', 'Hao', 'Xue', 'Xi']
re_words = [word[::-1] for word in a]
result = ' '.join(re_words)print(result)

【补充】回文数题型

方式一:回文数的基本思路:

def f(n):temp = nans = 0while temp>0:ans = ans*10 + temp%10temp = int(temp/10)return ans

方式二:字符串特性

n=input()
n2=n[::-1]

4、判断某字符是否包含于字符串内(STL+KMP)

n = input().strip()
if "No Information" in n:print("???")
elif "is greater than" in n:parts = n.split()a = int(parts[0])b = int(parts[-1])if a>b:print("Yes")else:print("No")
------------------------------------
输入:10 is greater than 5
输出:Yes
------------------------------------

5、公共前缀

给定n个字符串,求它们的公共前缀。

num = int(input())
#列表:其中for _ in range(num)表示循环num次,其中下划线 _ 通常用来忽略不需要返回值的循环变量
strings = [input().strip() for _ in range(num)]  # 常规写法 common = []
min_length = min(len(s) for s in strings)for i in range(min_length):temp = strings[0][i]if all(s[i]==temp for s in strings):common.append(temp)else:breakprint(''.join(common))
-------------------------------
输入:3actrpgactfpsactarpg
输出:act
-------------------------------

6、持续输入(遇到0停)

输入两个正整数a和b,求a+b的值。当a和b同时为0时停止执行。

while 1:# 返回的是数字a,b=list(map(int,input().split()))if a==0 and b==0:breakprint(a+b)
-------------------------
输入:2 31 87 90 0
输出:5916
-------------------------

7、排序题型【sorted题型】

给定n个考生的姓名、语文分数、数学分数,按下面三种排序要求之一进行排序:

  1. 按语文分数从高到低排序,分数相同时按姓名字典序从小到大排序
  2. 按数学分数从高到低排序,分数相同时按姓名字典序从小到大排序
  3. 按总分(语文+数学)从高到低排序,分数相同时按姓名字典序从小到大排序

输入描述

第一行两个整数n(1≤n≤1000)、k(1≤k≤3),分别表示考生个数、排序方式(k=1时表示按第一种方式排序,k=2时表示按第二种方式排序,k=3时表示按第三种方式排序);

接下来n行,每行为一个考生的姓名name、语文分数score1、数学分数score2(name为仅由大小写字母组成的不超过15个字符的字符串,0≤score≤100),用空格隔开。数据确保不会出现相同的姓名。

输出描述

输出排序后的结果,共n行,每行为一个考生的姓名、语文分数、数学分数、总分,用空格隔开。

m,n = list(map(int,input().split()))
# tuple相当于struct结构体
students = [tuple(input().split()) for _ in range(m)]# 新添tuple元素:总分
for i in range(len(students)):n1,s1,s2 = students[i]new = int(s1)+int(s2)students[i] = (n1,s1,s2,new)if n == 1:sorted_students = sorted(students,key=lambda x:(-int(x[1]),x[0]))
elif n == 2:sorted_students = sorted(students,key=lambda x:(-int(x[2]),x[0]))
elif n == 3:sorted_students = sorted(students,key=lambda x:(-int(x[3]),x[0]))for name,score1,score2,total in sorted_students:print(name,score1,score2,total)
---------------------------------------------------------
输入:5 1SunWuKong 92 88ShaWuJing 90 92TangSanZang 100 100BaiLongMa 90 88ZhuBaJie 87 91
输出:TangSanZang 100 100 200SunWuKong 92 88 180BaiLongMa 90 88 178ShaWuJing 90 92 182ZhuBaJie 87 91 178
---------------------------------------------------------

sorted讲解:

顺序:sorted(序列)

倒序:sorted(序列,reverse=True)

对其中某个部分进行排序:sorted(序列,key=lambda x:(x[3],x[0],…))

8、Python中实现数据结构模型

1:String类型【STL】

字符串【拼接】
a,b=input().split()
print(a+b)
--------------------------
输入:good bad
输出:goodbad
--------------------------
字符串【比较】
a,b=input().split()if a==b:print(0)
elif a>b:print(1)
else:print(-1)
----------------------
输入:good bad
输出:1
----------------------
字符串【长度】和【清空】
# 读取输入字符串
s = input()# 输出【字符串的长度】
print(len(s), end=" ")# 【清空】字符串
s = ""# 再次输出字符串的长度
print(len(s))
字符串的【插入】与【删除指定位置字符】
# 读取输入字符串
s = input().strip()
# 读取插入操作的参数
k1, c = input().strip().split()
k1 = int(k1)
# 读取删除操作的参数
k2 = int(input().strip())# 【插入元素】
s = s[:k1] + c + s[k1:]
print(s)# 【删除指定位置的元素】
s = s[:k2] + s[k2+1:]
print(s)
------------------------------------
输入:good2 u3
输出:gouodgoud
------------------------------------
判断是否为【子串】

使用s1.find(s2)函数判断s2是否是s1的子串,如果是的话,输出s2第一次在s1中出现的起始位置;如果不是,那么输出-1。

# 读取输入的两个字符串
s1, s2 = input().split()# 使用find方法查找s2在s1中的位置
pos = s1.find(s2)# 输出查找结果
print(pos)
字符串【替换】
# 输入
s1=input()
a,lens=list(map(int,input().split()))
a=int(a)
lens=int(lens)
s2=input()# 将s1中下标从a开始,长度为lens的子串替换为s2
new=s1.replace(s1[a:a+lens],s2)
print(new)

【思想】:字符串删除特定元素

a="abbcdd"
temp=[]
for i in range(len(a)):if a[i]=='b':continuetemp.append(a[i])
new_a=''.join(temp)
print(new_a)
【延伸题】:ds的字符串

ds 给了 xf 一个字符串。ds 对字符串可以进行若干次(可能是 0 次)如下操作:选择子串 “ds” 或者子串 “xf”,将其从字符串中删去。求最后剩下字符串的最短长度。子串是指原字符串中下标连续的一段字符串。

n=int(input())
strings=input()temp=stringswhile ('xf' in temp) or ('ds' in temp):lens=len(temp)li=[]for i in range(lens):li.append(temp[i])if len(li)>=2:if ''.join(li[-2:])=='ds':li.pop()li.pop()if ''.join(li[-2:])=='xf':li.pop()li.pop()temp=''.join(li)print(len(temp))
-------------------------------------
输入:10 # 长度xdsxffxacf # 字符串
输出:4
-------------------------------------

2:栈类型【先进后出】

stack=[]# 添加新元素至栈中
stack.append(1)
stack.append(2)
stack.append(3)
print(f"添加元素:%s" % stack)
# 删除栈顶【先进后出】❤
stack.pop()
print(f"删除栈顶元素:%s" % stack)
# 查询栈顶
num=stack[len(stack)-1]
print(f"查询栈顶元素:%s" % num)
# 判断栈是否为空
print(stack == [])
# 判断栈元素个数
print(f"判断栈元素个数:%d" % len(stack))
------------------------------------
添加元素:[1, 2, 3]
删除栈顶元素:[1, 2]
查询栈顶元素:2
False
判断栈元素个数:2
------------------------------------

3:双端队列

# 创建一个空的列表作为双端队列
deque_list = []# 在双端队列的右侧添加元素
deque_list.append('a')
deque_list.append('b')
print(deque_list)  # 输出: ['a', 'b']# 在双端队列的左侧添加元素
deque_list.insert(0, 'c')
print(deque_list)  # 输出: ['c', 'a', 'b']# 从双端队列的右侧移除并返回元素
right_element = deque_list.pop()
print(right_element)  # 输出: 'b'
print(deque_list)  # 输出: ['c', 'a']# 从双端队列的左侧移除并返回元素
left_element = deque_list.pop(0)
print(left_element)  # 输出: 'c'
print(deque_list)  # 输出: ['a']

4:队列类型【先进先出】

queue=[]# 添加新元素至队列中
queue.append(1)
queue.append(2)
queue.append(3)
print(f"添加元素:%s" % queue)
# 删除队列元素【先进先出】❤
queue.pop(0)
print(f"删除栈顶元素:%s" % queue)
# 查询队列首个元素
num=queue[0]
print(f"查询栈顶元素:%s" % num)
# 判断栈是否为空
print(queue == [])
# 判断栈元素个数
print(f"判断栈元素个数:%d" % len(queue))
------------------------------------
添加元素:[1, 2, 3]
删除栈顶元素:[2, 3]
查询栈顶元素:2
False
判断栈元素个数:2
------------------------------------

5:Set集合

基本语法
# 定义
1、语法:变量名={元素1,元素2,元素3,...}
2、注意:内部无序,且去重【不支持重复元素】,允许被修改
3、案例:set1 = {1,2,3} # set集合定义set2 = set() # set空集合定义
4、【不支持下标索引访问】
常用操作方法

my_set={"你好","china","beauty"}# 添加新元素add
my_set.add("三玖")
print(my_set)
------------------------------------
{'beauty', 'china', '你好', '三玖'}
------------------------------------# 移除元素remove
my_set.remove("你好")
print(my_set)
----------------------
{'beauty', 'china'}
----------------------# 随机取出一个元素pop
element = my_set.pop()
print(f"集合被取出的元素:{element},去除元素后:{my_set}")
----------------------------------------------------
集合被取出的元素:china,去除元素后:{'你好', 'beauty'}
----------------------------------------------------# 清空set集合clear
my_set.clear()
print(my_set)
----------
set()
----------# 取两个集合差集difference => 注意点:结果会得到一个新的集合,集合1和集合2不变【差集】
set1 = {1,2,3}
set2 = {1,5,6}
set3 = set1.difference(set2) # 取出set1和set2差集(set1有而set2没有)
print(f"去除差集后的结果:{set3}")
-----------------------
去除差集后的结果:{2, 3}
-----------------------# 消除两个集合差集difference_update => 注意点:集合1被修改,集合2不变【差集】
set1 = {1,2,3}
set2 = {1,5,6}
set1.difference_update(set2) # set1中,删除和set2相同的元素
print(f"去除差集后,set1的结果:{set1}")
print(f"去除差集后,set2的结果:{set2}")
----------------------------
去除差集后,set1的结果:{2, 3}
去除差集后,set2的结果:{1, 5, 6}
----------------------------# 两集合合并union【交集】
set1 = {1,2,3}
set2 = {1,5,6}
new_set = set1.union(set2)
print(new_set)
------------------
{1, 2, 3, 5, 6}
------------------# 统计集合元素数量len
set = {1,2,3}
cnt = len(set)
print(cnt)
-----------
3
-----------# 集合遍历 => 只支持for循环

python经典题型

一:双指针

1、序列合并【典型写法】

给定两个升序的正整数序列A和B,将它们合并成一个新的升序序列并输出。

n,m=list(map(int,input().split())) # 两行的长度
a=list(map(int,input().split()))
b=list(map(int,input().split()))# 合并两个升序序列
i,j=0,0
merged = []while i<n and j<m:if a[i]<=b[j]:merged.append(a[i])i+=1else:merged.append(b[j])j+=1# 将剩余的元素加入到结果中去
while i<n:merged.append(a[i])i+=1
while j<m:merged.append(b[j])j+=1for i in range(len(merged)):if i<len(merged)-1:print(merged[i],end=' ')else:print(merged[i],end='')
------------------------------------------
输入:4 31 5 6 82 6 9
输出:1 2 5 6 6 8 9
------------------------------------------

2、2-SUM-双指针【典型写法】

给定一个严格递增序列A和一个正整数k,在序列A中寻找不同的下标i、j,使得Ai+Aj=k。问有多少对(i,j)同时i<j满足条件。

size,target=list(map(int,input().split()))
array=list(map(int,input().split()))# 存放结果数
result=0
# 定义指针
i=0
j=size-1# 双指针遍历求解
while i<j:if array[i]+array[j]==target:result+=1i+=1j-=1elif array[i]+array[j]<target:i+=1else:j-=1print(result)
--------------------------------
输入:5 61 2 4 5 6
输出:2
--------------------------------

解释:1 + 5 = 6、2 + 4 = 6,因此有两对

3、集合交集

给定一个包含n个正整数的集合S1,再给定一个包含m个正整数的集合S2,求两个集合的交集。

n,m=list(map(int,input().split()))
a=list(map(int,input().split()))
b=list(map(int,input().split()))# 排序
a=sorted(a)
b=sorted(b)# 定义指针 与 结果集
i=0
j=0
result=[]# 双指针遍历求解
while i<n and j<m:if a[i]==b[j]:result.append(a[i])i+=1j+=1elif a[i]<b[j]:i+=1else:j+=1for i in range(len(result)):if i<len(result)-1:print(result[i],end=' ')else:print(result[i],end='')
----------------------------------------
输入:5 41 2 5 6 82 4 6 7
输出:2 6
----------------------------------------

4、集合并集

给定一个包含n个正整数的集合S1,再给定一个包含m个正整数的集合S2,求两个集合的并集。

n,m=list(map(int,input().split()))
a=list(map(int,input().split()))
b=list(map(int,input().split()))# 排序
a=sorted(a)
b=sorted(b)# 定义指针 与 结果集
i=0
j=0
result=[]# 双指针遍历求解
while i<n and j<m:if a[i]==b[j]:result.append(a[i])i+=1j+=1elif a[i]<b[j]:result.append(a[i])i+=1else:result.append(b[j])j+=1
# 将剩余的元素加入到结果中去
while i<n:result.append(a[i])i+=1
while j<m:result.append(b[j])j+=1for i in range(len(result)):if i<len(result)-1:print(result[i],end=' ')else:print(result[i],end='')
----------------------------------------
输入:5 41 2 5 6 82 4 6 7
输出:1 2 4 5 6 7 8
----------------------------------------

5、集合差集

给定一个包含n个正整数的集合S1,再给定一个包含m个正整数的集合S2,求两个集合的差集,即S1−S2。

注:使用双指针法完成。

n,m=list(map(int,input().split()))
a=list(map(int,input().split()))
b=list(map(int,input().split()))# 排序
a=sorted(a)
b=sorted(b)# 定义指针 与 结果集
i=0
j=0
result=[]# 双指针遍历求解
while i<n and j<m:if a[i]==b[j]:i+=1j+=1elif a[i]<b[j]:result.append(a[i])i+=1else:j+=1
# 将剩余的元素加入到结果中去
while i<n:result.append(a[i])i+=1for i in range(len(result)):if i<len(result)-1:print(result[i],end=' ')else:print(result[i],end='')
----------------------------------------
输入:5 41 2 5 6 82 4 6 7
输出:1 5 8
----------------------------------------

6、美丽的区间【区间和】

题目大意:求序列里区间和大于或等于常数s的最小区间长度

给定一个长度为 n 的序列 a1,a2,⋯,an 和一个常数 S。对于一个连续区间如果它的区间和大于或等于 S,则称它为美丽的区间。对于一个美丽的区间,如果其区间长度越短,它就越美丽。请你从序列中找出最美丽的区间。

n,s=list(map(int,input().split()))
a=list(map(int,input().split()))i,j=0,0 # 双指针
sum = 0 # 记录【区间和】
lens=10000000000000while i < len(a):if sum < s:sum+=a[i]i+=1else:if lens > i-j:lens = i-jsum -= a[j]j+=1
if lens==10000000000000:print(0)
else:print(lens)
----------------------------------
输入:5 6 # n=5,s=61 2 3 4 5
输出:2
----------------------------------

二:二分查找

基本题型

在一个严格递增序列A中寻找一个指定元素x,如果能找到,那么输出它的下标;如果不能找到,那么输出−1。

注:使用二分法实现。

size,target=list(map(int,input().split())) # 元素的个数、需要寻找的元素
a=list(map(int,input().split()))def f(a,size,target):left=0right=size-1while left <= right:mid=left+(right-left)//2if a[mid]==target:return midelif a[mid]<target:left=mid+1else:right=mid-1return -1print(f(a,size,target))
-------------------------------
输入:5 31 2 3 5 8
输出:2
-------------------------------
【延伸】单峰序列❤

单峰序列是指,在这个序列中存在一个位置,满足这个位置的左侧(含该位置)是严格递增的、右侧(含该位置)是严格递减的,这个位置被称作峰顶位置。现在给定一个单峰序列,求峰顶位置的下标。

n=int(input())
a=list(map(int,input().split()))def f(n,a):left=0right=n-1while left<right:mid = int((left+right)/2)if a[mid]<a[mid-1]:right=midelse:left=mid+1return left-1print(f(n,a))
-------------------------------------
输入:51 3 5 2 1
输出:2
-------------------------------------
【延伸】木棒切割问题

给出n根木棒的长度,现在希望通过切割它们来得到至少k段长度相等的木棒(长度必须是整数),问这些长度相等的木棒的最大长度。

n,k=map(int,input().split())
a = list(map(int,input().split()))def f(n,k,a):l=0r=10**5while l<r:mid = (l + r + 1) // 2  # 计算中间值stick_count=sum(x//mid for x in a)if stick_count<k:r=mid-1else:l=midreturn lprint(f(n,k,a))
--------------------------------------
输入:3 710 24 15
输出:6
--------------------------------------

解释

对三根长度分别为10、24、15的木棒来说,k=7,即需要至少7段长度相等的木棒,此时可以得到最大长度为6,因为在这种情况下,第一根木棒可以提供10/6=1段、第二根木棒可以提供24/6=4段、第三根木棒可以提供15/6=2段,达到了7段的要求。

【延伸】分巧克力

儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。

小明一共有 N 块巧克力,其中第 i 块是 Hi×Wi 的方格组成的长方形。为了公平起见,

小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:

  1. 形状是正方形,边长是整数;
  2. 大小相同;

例如一块 6×5 的巧克力可以切出 6 块 2×2 的巧克力或者 2 块 3×3 的巧克力。

当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?

n,k = list(map(int,input().split()))
a=[]
for _ in range(n):x=list(map(int,input().split()))a.append(x)def f(x):count=0for j in range(len(a)):x1=a[j][0]y1=a[j][1]count+=(x1//x)*(y1//x) # 数量return countleft=1
right=10000000
while left<=right:mid=(left+right)//2sums=f(mid)if sums<k:right=mid-1elif sums>=k:left=mid+1print(right)
------------------------------------------
输入:2 106 55 6
输出:2
------------------------------------------

三:并查集

并查集的基本写法初始化查询合并

1、合根植物

w 星球的一个种植园,被分成 m×n个小格子(东西方向 m 行,南北方向 n 列)。每个格子里种了一株合根植物。

这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。

如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?

m,n=map(int,input().split())ans=m*n # 单独集合数量# 【初始化】
nums=[i for i in range(m*n+1)]
#寻找父节点【寻找】
def find_root(x):if x==nums[x]:return xnums[x]=find_root(nums[x])return nums[x]
# 【合并】
def merge(x,y):global ans# 找到 l 和 r 的根节点x_root=find_root(x)y_root=find_root(y)# 如果 l 和 r 的根节点不同,说明它们原本不属于同一个集合if x_root!=y_root:nums[x_root] = nums[y_root] ans-=1 # 每次合并操作后,独立集合的数量减少 1k=int(input())
# 对于每组数据,读取两个整数 l 和 r,表示要将 l 和 r 所在的集合合并。
for i in range(k):# 找到 l 和 r 的根节点l,r=map(int,input().split())merge(l,r)
print(ans)
---------------------------------------------
输入:5 4 # m行 n列16 # k为162 31 55 94 87 89 1010 1111 1210 1412 1614 1817 1815 1919 209 1313 17
输出:5
---------------------------------------------

2、蓝桥幼儿园

蓝桥幼儿园的学生是如此的天真无邪,以至于对他们来说,朋友的朋友就是自己的朋友。小明是蓝桥幼儿园的老师,这天他决定为学生们举办一个交友活动,活动规则如下:

小明会用红绳连接两名学生,被连中的两个学生将成为朋友。

小明想让所有学生都互相成为朋友,但是蓝桥幼儿园的学生实在太多了,他无法用肉眼判断某两个学生是否为朋友。于是他起来了作为编程大师的你,请你帮忙写程序判断某两个学生是否为朋友(默认自己和自己也是朋友)。

输入描述
第 1 行包含两个正整数 N,M,其中 N 表示蓝桥幼儿园的学生数量,学生的编号分别为 1∼N。

之后的第 2∼M+1 行每行输入三个整数,op,x,y:

如果 op=1,表示小明用红绳连接了学生 x 和学生 y 。
如果 op=2,请你回答小明学生 x 和 学生 y 是否为朋友。

输出描述
对于每个 op=2 的输入,如果 x 和 y 是朋友,则输出一行 YES,否则输出一行 NO。

n,m=list(map(int,input().split()))# 【初始化】
a=[i for i in range(n+1)]#寻找父节点【寻找】
def find_root(x):if x==a[x]:return xa[x]=find_root(a[x])return a[x]# 【合并】
def merge(x,y):x_root=find_root(x)y_root=find_root(y)if x_root!=y_root:a[x_root]=a[y_root]for i in range(m):op,x,y=list(map(int,input().split()))if op==1:merge(x,y)elif op==2:x_root=find_root(x)y_root=find_root(y)if x_root==y_root:print("YES")else:print("NO")
---------------------------------------------
输入:5 5 2 1 21 1 32 1 31 2 3 2 1 2
输出:NOYESYES
---------------------------------------------

四:STL + KMP

KMP算法是一种用于解决字符串匹配问题的经典算法,它的核心思想是利用已经匹配过的信息,避免不必要的匹配尝试,从而提高匹配效率。

5.1、理论篇

5.2、实战篇

Next数组【前缀表】

next数组是KMP算法中的一个关键概念,它记录了模式串中每个位置的最长相同前后缀的长度。

在字符串匹配的KMP算法中有一个重要的概念是next数组,next数组的直接语义是:使“长度为L的前缀”与“长度为L的后缀”相同的最大L,且满足条件的前后缀不能是原字符串本身。

例如对字符串ababa来说,长度为1的前缀与后缀都是a,它们相同;长度为2的前缀与后缀分别是abba,它们不相同;长度为3的前缀与后缀都是aba,它们相同;长度为4的前缀与后缀分别是ababbaba,它们不相同。因此对字符串ababa来说,使“长度为L的前缀”与“长度为L的后缀”相同的最大L3

我们把这个最大的L值称为原字符串Snext值。在此概念的基础上,对给定的字符串S,下标为从1n,那么next[i]就是指子串S[1...i]next值。

现在给定一个字符串,求next数组每一项的值。

# next数组,用于填充这个数组
# s为模式串
def get_next(next,s):# 初始化j=0 # 前缀末尾位next[0]=0# i为后缀末尾位for i in range(1,len(s)):# 前后位不匹配,j边界就是0【循环过程】while j>0 and s[i] != s[j]:# j回退到前一位对应的next表中的值j=next[j-1]# 前后缀相同情况if s[i]==s[j]:j+=1# 更新next数组next[i]=jreturn nexts=input()
next1=[0]*len(s) # 初始化next长度
next=get_next(next1,s)
for i in range(0,len(s)):if i<len(s)-1:print(next[i],end=' ')else:print(next[i],end='')
-----------------------------------------
输入:ababaa
输出:0 0 1 2 3 1
-----------------------------------------

解释

子串a的最长相等前后缀不存在(因为不能等于本身),因此L=0

子串ab的最长相等前后缀不存在,因此L=0

子串aba的最长相等前后缀是a,因此L=1

子串abab的最长相等前后缀是ab,因此L=2

子串ababa的最长相等前后缀是aba,因此L=3

子串ababaa的最长相等前后缀是a,因此L=1

子串判定

现有两个字符串s1和s2,使用KMP算法判断s2是否s1的子串。

s1=input() # 文本串
s2=input() # 模式串# next数组
def get_next(next,s):# 初始化j=0 # 前缀末尾位next[0]=0# i为后缀末尾位for i in range(1,len(s)):# 前后位不匹配,j边界就是0【循环过程】while j>0 and s[i] != s[j]:# j回退到前一位对应的next表中的值j=next[j-1]# 前后缀相同情况if s[i]==s[j]:j+=1# 更新next数组next[i]=jreturn nextdef KMP(s1,s2):n=len(s1) # 文本串m=len(s2) # 模拟串next=[0]*len(s2) # 初始化next长度if m==0:return Truenext=get_next(next,s2)j=0for i in range(0,len(s1)):# s1对应元素 与 s2对应元素 不匹配while j>0 and s1[i] != s2[j]:j=next[j-1]# s1对应元素 与 s2对应元素 匹配if s1[i]==s2[j]:j+=1if j==len(s2):return Truereturn Falseresult=KMP(s1,s2)
print("Yes" if result else "No")
----------------------------------------
输入:abadcbac
输出:No
----------------------------------------

偷懒技巧

s1=input() # 文本串
s2=input() # 模式串if s2 in s1:print("Yes")
else:print("No")

五:递归和递推

回溯法】,一般可以解决如下几种问题:

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

基本框架

void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {处理节点;backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

1、数的计算

输入一个自然数 n (n≤1000),我们对此自然数按照如下方法进行处理:

  1. 不作任何处理;
  2. 在它的左边加上一个自然数,但该自然数不能超过原数的一半;
  3. 加上数后,继续按此规则进行处理,直到不能再加自然数为止。

问总共可以产生多少个数。

def f(n):if n==1:return 1num=1for i in range(1,n//2+1):num=num+f(i)return numn=int(input())
print(f(n))
-----------------------------
输入:6
输出:6
-----------------------------

2、汉诺塔题型

汉诺塔(又称河内塔)问题源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

抽象成模型就是说:

有三根相邻的柱子,标号分别为A、B、C,A柱子按金字塔状叠放着n个不同大小的圆盘,现在要把所有盘子一个一个移动到柱子C上,并且任何时候同一根柱子上都不能出现大盘子在小盘子上方,请问至少需要多少次移动,并给出具体的移动方案。

输入:一个正整数n(1≤n≤16),表示圆盘的个数。

输出

​ 第一行输出一个整数,表示至少需要的移动次数。

​ 接下来每行输出一次移动,格式为X->Y,表示从柱子X移动最上方的圆盘到柱子Y最上方。

def f(n,from_rod,to_rod,mid_rod):if n==0:return# 将前n-1个盘子从from_rod到mid_rod,借助to_rod作为辅助f(n-1,from_rod,mid_rod,to_rod)# 将第n个盘子直接从from_rod移到to_rodprint(f"{from_rod}->{to_rod}")# 将前n-1个盘子从mid_rod到to_rod,借助from_rod作为辅助f(n-1,mid_rod,to_rod,from_rod)n = int(input())
print(2**n-1)
f(n,'A','C','B')

3、 数字螺旋矩阵

给定一个正整数n,生成一个大小为n∗n的方阵,其中按顺时针的顺序给出从1到n∗n的每一个整数。

如下图是n=5的螺旋矩阵。

def f(n):# 初始化n * n的矩阵:[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]matrix=[[0]*n for _ in range(n)]index=1def fill_matrix(x,y,size):nonlocal indexif size == 0:returnif size == 1:matrix[x][y] = indexindex+=1return# 填充最上边的行for i in range(y,y+size-1):matrix[x][i]=indexindex+=1# 填充最右边的列for i in range(x,y+size-1):matrix[i][y+size-1]=indexindex+=1# 填充最下边的行for i in range(y+size-1,y,-1):matrix[x+size-1][i] = indexindex+=1# 填充最左边的行for i in range(x+size-1,x,-1):matrix[i][y]=indexindex+=1# 递归填充内圈fill_matrix(x+1,y+1,size-2)fill_matrix(0,0,n)return matrixn=int(input())# [[1, 2, 3, 4, 5], [16, 17, 18, 19, 6], [15, 24, 25, 20, 7], [14, 23, 22, 21, 8], [13, 12, 11, 10, 9]]
result=f(n) for row in result:for i in range(len(row)):if i<len(row)-1:print(row[i],end=' ')else:print(row[i])
-------------------------------
输入:5
输出:1 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9
-------------------------------

六、基础题

1、卡片

小蓝有 k 种卡片, 一个班有 n 位同学, 小蓝给每位同学发了两张卡片, 一 位同学的两张卡片可能是同一种, 也可能是不同种, 两张卡片没有顺序。没有 两位同学的卡片都是一样的。

给定 n , 请问小蓝的卡片至少有多少种?

注意C计算两种不同的卡片【比如(1,2)(1,3)(2,3)】,题目中还可以相同的卡片【比如(1,1)(2,2)(3,3)】,因此需要加k

n=int(input())k=1
while 1:if k*(k+1)/2 >= n:print(k)breakelse:k+=1
----------------------------
输入:6
输出:3
----------------------------

2、水仙花数

如果一个三位数 n 的各位数字的立方和等于 n ,那么称 n 为水仙花数。例如 153=13+53+3^3,因此 153 是水仙花数。

给定一个正整数,判断这个数是否是水仙花数。

n = int(input())temp = nbai = temp // 100
shi = (temp // 10) % 10
ge = temp%10if ge**3+bai**3+shi**3 == n:print("YES")
else:print("NO")
---------------------------------
输入:153
输出:YES
---------------------------------

七、Hash法【补充】

给定一个严格递增序列A和一个正整数k,在序列A中寻找不同的下标i、j,使得Ai+Aj=k。问有多少对(i,j)同时i<j满足条件。

注:使用hash法实现

def find(n, k, A):# 初始化hash表,大小为10^6+1hashTable = [False] * (10 ** 6 + 1)# 填充hash表for num in A:hashTable[num] = Truecount = 0# 查找数对for num in A:if k - num >= 0 and hashTable[k - num]:count += 1# 每个数对被找到两次,所以结果需要除以 2return count // 2n, m = map(int, input().split())
A = list(map(int, input().split()))print(find(n, m, A))
------------------------
输入:5 61 2 4 5 6
输出:2
------------------------

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/77510.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Kubernetes】Kubernetes 如何进行日志管理?Fluentd / Loki / ELK 适用于什么场景?

由于 Kubernetes 运行在容器化的环境中&#xff0c;应用程序和系统日志通常分布在多个容器和节点上&#xff0c;传统的日志管理方法&#xff08;例如直接访问每个节点的日志文件&#xff09;在 Kubernetes 中不适用。 因此&#xff0c;Kubernetes 引入了集中式日志管理方案&am…

Ansible(8)——循环与条件任务

目录 一、循环迭代任务&#xff1a; 1、简单循环&#xff1a; 2、循环字典列表&#xff1a; 3、Ansible 2.5 之前的循环关键字&#xff1a; 4、在循环中使用 register 变量&#xff1a; 二、条件任务&#xff1a; 1、使用条件句的常见场景&#xff1a; 2、条件任务语法…

adb|scrcpy的安装和配置方法|手机投屏电脑|手机声音投电脑|adb连接模拟器或手机

adb|scrcpy的安装和配置方法手机投屏电脑|手机声音投电脑|adb连接模拟器或手机或电视 引言 在数字设备交织的现代生活中&#xff0c;adb&#xff08;Android Debug Bridge&#xff09;与 scrcpy 宛如隐匿的强大工具&#xff0c;极大地拓展了我们操控手机、模拟器乃至智能电视等…

vue3项目集成electron

一、环境准备 1. 确保已安装 Node.js (建议版本 16.x 或更高) 2. 创建或进入现有 Vue 项目目录 cd your-vue-project 二、添加 Electron 支持 在项目根目录执行: vue add electron-builder 执行后会在 `src` 目录下生成 `background.js` 主进程文件。 三、主进程配置 (ba…

循环神经网络 - 参数学习之随时间反向传播算法

本文中&#xff0c;我们以同步的序列到序列模式为例来介绍循环神经网络的参数学习。 循环神经网络中存在一个递归调用的函数 &#x1d453;(⋅)&#xff0c;因此其计算参数梯度的方式和前馈神经网络不太相同。在循环神经网络中主要有两种计算梯度的方式&#xff1a;随时间反向…

体验OceanBase的 并行导入功能

在数据库的日常使用中&#xff0c;会经常遇到以下场景&#xff1a; ‌数据复制‌&#xff1a;将一个或多个表中的数据复制到目标表中&#xff0c;可能是复制全部数据&#xff0c;也可能仅复制部分数据。数据合并&#xff1a;将数据从一个表转移到另一个表&#xff0c;或者将多…

Kafka和RocketMQ相比有什么区别?那个更好用?

Kafka和RocketMQ相比有什么区别?那个更好用? Kafka 和 RocketMQ 都是广泛使用的消息队列系统&#xff0c;它们有很多相似之处&#xff0c;但也有一些关键的区别。具体选择哪个更好用&#xff0c;要根据你的应用场景和需求来决定。以下是它们之间的主要区别&#xff1a; 1. …

UniApp 实现兼容 H5 和小程序的拖拽排序组件

如何使用 UniApp 实现一个兼容 H5 和小程序的 九宫格拖拽排序组件&#xff0c;实现思路和关键步骤。 一、实现目标 支持拖动菜单项改变顺序拖拽过程实时预览移动位置拖拽松开后自动吸附回网格兼容 H5 和小程序平台 二、功能结构拆解以及完整代码 完整代码&#xff1a; <…

[raspberrypi 0w and respeaker 2mic]实时音频波形

0. 环境 ubuntu22主机&#xff0c; 192.168.8.162&#xff0c; raspberry 0w&#xff0c; 192.168.8.220 路由器 1. 树莓派 # rpi - send.py # 或者命令行&#xff1a;arecord -D plughw:1,0 -t wav -f cd -r 16000 -c 2 | nc 192.168.8.162 12345import socket imp…

公司内部建立apt源

有一篇建立pypi源的在这里需要的可以查看&#xff1a;公司内部建立pypi源-CSDN博客 背景&#xff0c;公司内部有很多工具仅供内部使用&#xff0c;如果用apt的方式就比较方便&#xff0c;只需要修改sources.list将源添加进去就可以了。我们接下来的操作就是为了实现这个需求。…

UE5中如何修复后处理动画蓝图带来的自然状态下的metablriger身体绑定形变(如耸肩)问题

【[metablriger] UE5中如何修复后处理动画蓝图带来的自然状态下的metablriger身体绑定形变(如耸肩)问题】 UE5中如何修复后处理动画蓝图带来的自然状态下的metablriger身体绑定形变(如耸肩)问题

AWS Bedrock生成视频详解:AI视频创作新时代已来临

💡 TL;DR: AWS Bedrock现已支持AI视频生成功能,让企业无需深厚AI专业知识即可创建高质量视频内容。本文详解Bedrock视频生成能力的工作原理、应用场景和实操指南,助你快速掌握这一革命性技术。 🎬 AWS Bedrock视频生成:改变内容创作的游戏规则 还记得几年前,制作一个专…

1.2 测试设计阶段:打造高质量的测试用例

测试设计阶段&#xff1a;打造高质量的测试用例 摘要 本文详细介绍了软件测试流程中的测试设计阶段&#xff0c;包括测试用例设计、测试数据准备、测试环境搭建和测试方案设计等内容。通过本文&#xff0c;读者可以系统性地了解测试设计的方法和技巧&#xff0c;掌握如何高效…

jQueryHTML与插件

1.jQuery 事件机制 1.1 注册事件 bind()、on()方法向被选元素添加一个或多个事件处理程序&#xff0c;以及当事件发生时运行的函数 $("p").on({"click": function () {alert("点击了")},"mouseenter": function () {…

MySQL 触发器与存储过程:数据库的自动化工厂

在数据世界的工业区&#xff0c;有一座运转高效的自动化工厂&#xff0c;那里的机器人日夜不停地处理数据…这就是 MySQL 的触发器与存储过程系统&#xff0c;它让数据库从"手工作坊"变成了"现代化工厂"… 什么是 MySQL 触发器与存储过程&#xff1f;&…

PostgreSQL-中文字段排序-修改字段的排序规则

最新版本更新 https://code.jiangjiesheng.cn/article/365?fromcsdn 推荐 《高并发 & 微服务 & 性能调优实战案例100讲 源码下载》 -- 修改字段的排序规则 ALTER TABLE "public"."your_table_name" ALTER COLUMN "name" TYPE varcha…

GitHub优秀项目:数据湖的管理系统LakeFS

lakeFS 是一个开源工具&#xff0c;它将用户的对象存储转换为类似Git的存储库。使用户可以像管理代码一样管理数据湖。借助 lakeFS&#xff0c;可以构建可重复、原子化和版本化的数据湖操作--从复杂的ETL作业到数据科学和分析。 Stars 数11090Forks 数3157 主要特点 强大的数据…

页面编辑器CodeMirror初始化不显示行号或文本内容

延迟刷新 本来想延迟100毫秒的&#xff0c;但是会出现样式向左偏移的情况&#xff0c;于是试了试500毫秒&#xff0c;发现就没有问题了&#xff0c;可能是样式什么是需要一个加载过程吧。 useEffect(() > {editorRef.current?.setValue(value || );setTimeout(() > {edi…

使用 Spring Boot 和 Uniapp 搭建 NFC 读取系统

目录 一、NFC 技术原理大揭秘1.1 NFC 简介1.2 NFC 工作原理1.3 NFC 应用场景 二、Spring Boot 开发环境搭建2.1 创建 Spring Boot 项目2.2 项目基本配置 三、Spring Boot 读取 NFC 数据3.1 NFC 设备连接与初始化3.2 数据读取逻辑实现3.3 数据处理与存储 四、Uniapp 前端界面开发…

台式电脑插入耳机没有声音或麦克风不管用

目录 一、如何确定插孔对应功能1.常见音频插孔颜色及功能2.如何确认电脑插孔?3.常见问题二、 解决方案1. 检查耳机连接和设备选择2. 检查音量设置和静音状态3. 更新或重新安装声卡驱动4. 检查默认音频格式5. 禁用音频增强功能6. 排查硬件问题7. 检查系统服务8. BIOS设置(可选…