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.pswp.cn/diannao/77510.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/77510.shtml
英文地址,請注明出處:http://en.pswp.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設置(可選…