25fall 做题记录-October
2025.10.5
Sale
n,m=map(int,input().split())
a=list(map(int,input().split()))
a.sort()
s=0
for i in range(len(a)):
if(a[i]<0 and i+1<=m):
s-=a[i]
if(a[i]>=0):
break
print(s)
Maya Calendar
这题很难评。注意整除的时候的特殊处理,0->13,年数整除260时会多出来一年。
n=int(input())
print(n)
dic_month={"pop":0,"no":1,"zip":2,"zotz":3,"tzec":4,"xul":5,"yoxkin":6,"mol":7,"chen":8,"yax":9,"zac":10,"ceh":11,"mac":12,"kankin":13,"muan":14,"pax":15,"koyab":16,"cumhu":17,"uayet":18}
name=["ahau","imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk","ok","chuen","eb","ben","ix","mem","cib","caban","eznab","canac"]
for i in range(n):
day,s=input().split('.')
day=int(day)
s=s.strip()
month,year=s.split()
year=int(year)
res=year*365+dic_month[month]*20+day+1
a=res%13
if(a==0):
a=13
c=res//260
if(res%260==0):
c-=1
print("%d %s %d" %(a,name[res%20],c))
2025.10.6
黑神话·悟空
状压dp。用17位二进制数存储是否已打败怪兽。dp数组记录打败某些怪兽所需的最少次数。复杂度为\(O(n*2^n)\).
bit_count()用oj过不了。直接用bin().count()计算二进制中1的个数。
a=list(map(int,input().split()))
n=len(a)
MAXM=float("inf")
dp=[MAXM for _ in range(1<<n)]#打掉bitmask中所有boss所需最少任务数
dp[0]=0
for i in range(1<<n):
gain=bin(i).count('1')+1
for j in range(n):
if(not (i>>j)&1):
t=i|(1<<j)
dp[t]=min(dp[t],dp[i]+(a[j]+gain-1)//gain)
print(dp[(1<<n)-1])
移动零
双指针。维护第一个零的位置。
class Solution:
def moveZeroes(self, nums: list[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
i0=0
for i in range(len(nums)):
if(nums[i]!=0):
nums[i0],nums[i]=nums[i],nums[i0]
i0+=1
return nums
print(Solution().moveZeroes([0,1,0,3,12]))
print(Solution().moveZeroes([0]))
Dragons
贪心+二维数组排序。注意看清题意,大于还是大于等于。
Python lambda(匿名函数)
s,n=map(int,input().split())
a=[]
for i in range(n):
t=list(map(int,input().split()))
a.append(t)
a=sorted(a,key=lambda t:t[0])
cur=s
flag=1
for i in range(n):
if(cur>a[i][0]):
cur+=a[i][1]
else:
flag=0
break
if(flag==0):
print("NO")
else:
print("YES")
搜索插入位置
二分查找。
class Solution:
def searchInsert(self, nums: list[int], target: int) -> int:
left=0
right=len(nums)-1
while(left<=right):
mid=(left+right)//2
if(nums[mid]>=target):
right=mid-1
else:
left=mid+1
return left
print(Solution().searchInsert([1,3,5,6],5))
print(Solution().searchInsert([1,3,5,6],2))
print(Solution().searchInsert([1,3,5,6],7))
print(Solution().searchInsert([1,3,5,6],0))
Xenia and Ringroad
n,m=map(int,input().split())
a=list(map(int,input().split()))
cur=1
ans=0
for i in range(m):
if(cur<=a[i]):
ans+=a[i]-cur
cur=a[i]
else:
ans+=n-cur+a[i]
cur=a[i]
print(ans)
多项式时间复杂度
特判0n和n.
a=list(input().strip().split('+'))
ans=0
for i in range(len(a)):
if('n' in a[i]):
x,y=a[i].split('n^')
if(x!='0'):
ans=max(ans,int(y))
print("n^%d" %(ans))
Equation
from math import sqrt
a,b,c=map(int,input().split())
if(a==0):
if(b==0):
if(c==0):
print(-1)
elif(c!=0):
print(0)
elif(b!=0):
print(1)
print("%.5f" %(-c/b))
else:
d=b*b-4*a*c
if(d<0):
print(0)
elif(d==0):
print(1)
print("%.5f" %((-b)/(2*a)))
else:
print(2)
x=(-b+sqrt(d))/(2*a)
y=(-b-sqrt(d))/(2*a)
if(x>y):
x,y=y,x
print("%.5f\n%.5f" %(x,y))
Holiday Hotel
while(True):
n=int(input())
if(n==0):
break
a=[]
for i in range(n):
t=list(map(int,input().split()))
a.append(t)
a=sorted(a,key=lambda t:(t[0],t[1]))
minm=a[0][1]
ans=1
for i in range(1,n):
if(a[i][1]<minm):
minm=a[i][1]
ans+=1
print(ans)
菲波那契数列
a=[0,1,1]
idx=2
for i in range(25):
a.append(a[idx-1]+a[idx])
idx+=1
n=int(input())
for i in range(n):
print(a[int(input())])
Ilya and Queries
前缀和。一开始写的位运算但是被首位0击败了。
s=input()
cal=0
pre=[]
for i in range(len(s)-1):
if(s[i]==s[i+1]):
cal+=1
pre.append(cal)
pre.append(cal)
m=int(input())
for i in range(m):
l0,r0=map(int,input().split())
if(l0==1):
print(pre[r0-2])
else:
print(pre[r0-2]-pre[l0-2])
Pasha and Pixels
n,m,k=map(int,input().split())
a=[[0 for _ in range(m+2)] for _ in range(n+2)]
ans=0
def check(i,j):
if(a[i-1][j-1]==1 and a[i-1][j]==1 and a[i][j-1]==1):
return True
if(a[i-1][j]==1 and a[i-1][j+1]==1 and a[i][j+1]==1):
return True
if(a[i][j-1]==1 and a[i+1][j-1]==1 and a[i+1][j]==1):
return True
if(a[i][j+1]==1 and a[i+1][j]==1 and a[i+1][j+1]==1):
return True
return False
for i in range(1,k+1):
x,y=map(int,input().split())
if(ans!=0):
continue
a[x][y]=1
if(check(x,y)):
ans=i
print(ans)
2025.10.8
矩阵运算(先乘再加)
m1,n1=map(int,input().split())
a=[]
for i in range(m1):
t=list(map(int,input().split()))
a.append(t)
m2,n2=map(int,input().split())
b=[]
for i in range(m2):
t=list(map(int,input().split()))
b.append(t)
m3,n3=map(int,input().split())
c=[]
for i in range(m3):
t=list(map(int,input().split()))
c.append(t)
if(n1!=m2 or m1!=m3 or n2!=n3):
print("Error!")
else:
m=m1
n=n1
p=n2
for i in range(m):
for j in range(p):
for k in range(n):
c[i][j]+=a[i][k]*b[k][j]
c[i][j]=str(c[i][j])
for i in range(m):
print(" ".join(c[i]))
二维矩阵上的卷积运算
m,n,p,q=map(int,input().split())
a=[]
b=[]
c=[[0 for _ in range(n+1-q)]for _ in range(m+1-p)]
for i in range(m):
t=list(map(int,input().split()))
a.append(t)
for i in range(p):
t=list(map(int,input().split()))
b.append(t)
for i in range(m+1-p):
for j in range(n+1-q):
for k in range(p):
for l in range(q):
c[i][j]+=b[k][l]*a[i+k][j+l]
c[i][j]=str(c[i][j])
for i in range(m+1-p):
print(" ".join(c[i]))
BerSU Ball
贪心+双指针。cf别惦记你那算法标签了。

n=int(input())
a=list(map(int,input().split()))
m=int(input())
b=list(map(int,input().split()))
a.sort()
b.sort()
i=0
j=0
ans=0
while(i<n and j<m):
if(abs(a[i]-b[j])<=1):
ans+=1
i+=1
j+=1
elif(a[i]<b[j]):
i+=1
elif(a[i]>b[j]):
j+=1
print(ans)
2025.10.9
Two Divisors
欧拉筛求最小质因数。只用开一个列表,[]*maxn比[range]占用空间小。
from math import sqrt
n=int(input())
a=list(map(int,input().split()))
b=[]
c=[]
primes=[]
MAXA=max(a)+1
#sieve_of_euler
div=[0]*MAXA
for i in range(2,MAXA):
if(div[i]==0):
div[i]=i
primes.append(i)
for j in primes:
if(j*i>=MAXA):
break
div[j*i]=j
if(i%j==0):
break
for i in range(n):
q=div[a[i]]
t=a[i]
while(t%q==0):
t/=q
if(t!=1):
b.append(str(int(t)))
c.append(str(int(a[i]/t)))
else:
b.append("-1")
c.append("-1")
print(" ".join(b))
print(" ".join(c))
公共前缀
n=int(input())
a=[]
lent=55
for i in range(n):
t=input()
a.append(t)
lent=min(lent,len(t))
for i in range(lent,0,-1):
q=a[0][0:i]
flag=1
ans=0
for j in range(1,n):
if(a[j][0:i]!=q):
flag=0
break
if(flag==1):
ans=1
print(q)
break
if(ans==0):
print("\n")
2025.10.10
圣诞老人的礼物-Santa Clau’s Gifts
n,w=map(int,input().split())
a=[]
for i in range(n):
x,y=map(int,input().split())
t=x/y
a.append([t,x,y])
a=sorted(a,key=lambda t:-t[0])
ans=0
for i in range(n):
if(w>a[i][2]):
w-=a[i][2]
ans+=a[i][1]
elif(0<w<=a[i][2]):
ans+=a[i][0]*w
break
else:
break
print("%0.1f" %(ans))
双向喜欢
n,q=map(int,input().split())
a=[[0 for _ in range(15)]for _ in range(15)]
for i in range(q):
x,y=map(int,input().split())
a[x][y]=1
flag=0
for i in range(n+1):
for j in range(n+1):
if(a[i][j]==1 and a[j][i]==1 and i!=j):
flag=1
break
if(flag==1):
print("Yes")
else:
print("No")
Bigram 分词
class Solution:
def findOcurrences(self, text: str, first: str, second: str) -> list[str]:
txt=list(text.split())
idx=0
res=[]
while(idx<=len(txt)-3):
if(txt[idx]==first and txt[idx+1]==second):
res.append(txt[idx+2])
idx+=1
return res
print(Solution().findOcurrences("alice is a good girl she is a good student","a","good"))
三方欢喜
n,q=map(int,input().split())
a=[[0 for _ in range(15)]for _ in range(15)]
for i in range(q):
x,y=map(int,input().split())
a[x][y]=1
flag=0
for i in range(n+1):
for j in range(n+1):
for k in range(n+1):
if(i==j or j==k or k==i):
continue
if(a[i][j]==1 and a[j][k]==1 and a[k][i]==1):
flag=1
break
if(flag==1):
print("Yes")
else:
print("No")
倒排索引
n=int(input())
a=[]
for i in range(n):
t=set(input().split())
a.append(t)
m=int(input())
for i in range(m):
word=input()
res=[]
flag=0
for j in range(n):
if(word in a[j]):
flag=1
res.append(j+1)
if(flag==1):
print(" ".join(map(str,res)))
else:
print("NOT FOUND")
无重复字符的最长子串
双指针,滑动窗口。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
a=set()
ans=0
r=0
for i in range(len(s)):
if(i!=0):
a.remove(s[i-1])
while(r<len(s) and s[r] not in a):
a.add(s[r])
r+=1
ans=max(ans,r-i)
return ans
print(Solution().lengthOfLongestSubstring("abcabcbb"))
字母异位词分组
1.字符串内部排序
2.defaultdict
from collections import defaultdict
class Solution:
def groupAnagrams(self, strs: list[str]) -> list[list[str]]:
res=defaultdict(list)
for i in range(len(strs)):
res["".join(sorted(strs[i]))].append(strs[i])
return list(res.values())
print(Solution().groupAnagrams(["eat","tea","tan","ate","nat","bat"]))
最长连续序列
set()查找为O(1).
range()耗时问题.
以每个数为开头查找。如果数列中包含x-1则跳过。
class Solution:
def longestConsecutive(self, nums: list[int]) -> int:
nums=set(nums)
ans=0
for i in nums:
if(i-1 in nums):
continue
else:
idx=i+1
while(idx in nums):
idx+=1
ans=max(ans,idx-i)
return ans
print(Solution().longestConsecutive([0,3,7,2,5,8,4,6,0,1]))
Another Divisibility Problem
n=int(input())
for i in range(n):
x=int(input())
y=999999999-x
print(y)
所有子字符串美丽值之和
class Solution:
def beautySum(self, s: str) -> int:
a=[0]*27
ans=0
for i in range(len(s)):
a=[0]*27
for j in range(i,len(s)):
a[ord(s[j])-97]+=1
maxm=0
minm=505
for k in range(26):
if(a[k]==0):
continue
maxm=max(maxm,a[k])
minm=min(minm,a[k])
ans+=maxm-minm
return ans
print(Solution().beautySum("aabcb"))
Cut Ribbon
注意dp数组初始化。没有答案的情况置-inf.
n,a,b,c=map(int,input().split())
dp=[float("-inf")]*(n+1)#切到长度n的最大片数
dp[0]=0
for i in range(min(a,b,c),n+1):
if (i - a >= 0):
dp[i] = max(dp[i], dp[i - a] + 1)
if (i - b >= 0):
dp[i] = max(dp[i], dp[i - b] + 1)
if (i - c >= 0):
dp[i] = max(dp[i], dp[i - c] + 1)
print(dp[n])
2025.10.11
吃糖果
n=int(input())
dp=[0,1,2]#i块的方案数
for i in range(3,n+1):
dp.append(dp[i-1]+dp[i-2])
print(dp[n])
八皇后
dfs.不要在标记状态的时候改变函数参数,直接在每一次搜索中修改。
n=int(input())
res=[]
#x=[0]*8
y=[0]*8
z=[0]*15
w=[0]*15
def dfs(step,lst):
if(step==8):
res.append(lst)
return
for i in range(8):
if(y[i]==0 and z[step+i]==0 and w[7+step-i]==0):
y[i]=1
z[step+i]=1
w[7+step-i]=1
dfs(step+1,lst+str(i+1))
y[i]=0
z[step+i]=0
w[7+step-i]=0
dfs(0,"")
for i in range(n):
t=int(input())
print(res[t-1])
(201911)护林员盖房子
二维前缀和。
m,n=map(int,input().split())
a=[]
for i in range(m):
t=list(map(int,input().split()))
a.append(t)
pre=[[0 for _ in range(n+1)]for _ in range(m+1)]#向右向下分别移动一位
pre[1][1]=a[0][0]
for i in range(1,m+1):
for j in range(1,n+1):
pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i-1][j-1]
ans=0
for i in range(1,m+1):
for j in range(1,n+1):
for p in range(i,m+1):
for q in range(j,n+1):
if(pre[p][q]-pre[i-1][q]-pre[p][j-1]+pre[i-1][j-1]==0):
ans=max(ans,(p-i+1)*(q-j+1))
print(ans)
护林员盖房子 加强版
最大子矩阵。转换为直方图最大矩形面积问题。对每一层考虑包含这一层的从上到下连续空地的最大长度,即为直方图的柱长。
悬线法:左右悬线,如果比当前高就用左侧的悬线长度更新当前悬线长度。(dp)
m,n=map(int,input().split())
a=[]
l=[0]*(n+1)
r=[0]*(n+1)
s=[0]*(n+1)
ans=0
for i in range(m):
l=list(map(int,input().split()))
a.append(l)
for i in range(m):
for j in range(n):
if(a[i][j]==0):
s[j]+=1
else:
s[j]=0
for j in range(n):
l[j]=r[j]=j
for j in range(n):
while(l[j]>0 and s[l[j]-1]>=s[j]):
l[j]=l[l[j]-1]
for j in range(n,-1,-1):
while(r[j]<n-1 and s[r[j]+1]>=s[j]):
r[j]=r[r[j]+1]
for j in range(n):
ans=max(ans,s[j]*(r[j]-l[j]+1))
print(ans)
咒语序列
用栈的思路解决。left,right分别记录左括号和右括号的数目,如果右括号多于左括号就同时置零,如果左==右就更新ans。
注意会有左括号始终多于右括号的情况,再从右往左扫一遍。
s=input()
left=0
right=0
ans=0
for i in range(len(s)):
if(s[i]=='('):
left+=1
else:
right+=1
if(right>left):
left=0
right=0
elif(left==right):
ans=max(ans,left*2)
s=s[::-1]
left=0
right=0
for i in range(len(s)):
if(s[i]==')'):
left+=1
else:
right+=1
if(right>left):
left=0
right=0
elif(left==right):
ans=max(ans,left*2)
print(ans)
2025.10.13
护林员盖房子 加强版
单调栈:仍然考虑每一根柱子左右第一个小于其高度的柱子。使用单调栈维护柱子的长度上升,如果遇到柱子长度变低就把不符合的柱子都弹出,弹出完剩下的栈顶就是左侧第一个小于其高度的柱子。而每个柱子只会被弹出一次,第一次使其弹出的柱子就是其右侧第一个小于等于其高度的柱子。注意右侧包含了柱子长度相等的情况,但是在这种情况下最右侧的那根柱子会保留正确答案。
单调栈可以解决一维数组中找到左右第一个小于该数的位置。如果需要确切的右边界,从右往左再扫一遍即可。
柱状图中最大的矩形
from collections import deque
m,n=map(int,input().split())
a=[]
s=[0]*n
l=[-1]*n
r=[n]*n
ans=0
t=deque()
for i in range(m):
l=list(map(int,input().split()))
a.append(l)
for i in range(m):
for j in range(n):
if(a[i][j]==0):
s[j]+=1
else:
s[j]=0
t.clear()
l = [-1]*n
r = [n]*n
for j in range(n):
while(t and s[j]<=s[t[-1]]):
r[t[-1]]=j
t.pop()
l[j]=t[-1] if t else -1
t.append(j)
for j in range(n):
ans=max(ans,s[j]*(r[j]-l[j]-1))
print(ans)
差分数组、扫描线
yhf在群里发的文档。
差分数组、扫描线,解释并python示例出来
“差分数组”和“扫描线(sweep line)”这两个算法思想非常常用,尤其在处理区间修改、区间计数、区间重叠等问题时。
下面我会逐步讲清楚它们的原理、区别、联系,并附上清晰的 Python 示例。
一、差分数组(Difference Array)
- 核心思想
差分数组是一种高效处理区间加减操作的技巧。
假设你有一个数组 a = [a1, a2, a3, ..., an],
构造它的差分数组 diff:
diff[i] = a[i] - a[i-1] (其中 a[0] 视为 0)
-
当要给区间
[l, r]中的所有元素 +x 时:diff[l] += x diff[r+1] -= x (如果 r+1 <= n)
最后,通过一次前缀和即可恢复出修改后的原数组。
- 示例:区间加法
题目
初始数组为 [0, 0, 0, 0, 0]
操作:
- 对区间 [1, 3] 加 2
- 对区间 [2, 4] 加 3
问最终数组?
代码
n = 5
a = [0] * n
diff = [0] * (n + 1)
# 区间加函数
def add(l, r, x):
diff[l] += x
if r + 1 < len(diff):
diff[r + 1] -= x
# 两次操作
add(1, 3, 2)
add(2, 4, 3)
# 还原结果
a[0] = diff[0]
for i in range(1, n):
a[i] = a[i - 1] + diff[i]
print(a) # [2, 5, 5, 3, 0]
✅ 输出解释:
- 第1步 [1,3]+2 →
[0,2,2,2,0] - 第2步 [2,4]+3 →
[0,2,5,5,3]
二、扫描线算法(Sweep Line)
- 核心思想
扫描线是处理区间重叠、事件统计的通用思想。
可以理解为一条“从左到右扫描”的直线,遇到事件点就改变当前状态。
在区间问题中,通常:
- 区间左端点代表“增加一个活动”
- 区间右端点代表“结束一个活动”
把所有端点事件放在一起排序,顺序扫描。
- 示例:统计同时在线人数最大值
题目
给出若干人的上网时间区间,求某一时刻同时在线的最大人数。
输入:
[1, 4]
[2, 5]
[7, 9]
输出:
2
代码
intervals = [(1, 4), (2, 5), (7, 9)]
events = []
for l, r in intervals:
events.append((l, 1)) # 进入 +1
events.append((r, -1)) # 离开 -1
events.sort() # 按时间排序
cur = 0
max_online = 0
for time, delta in events:
cur += delta
max_online = max(max_online, cur)
print(max_online) # 2
✅ 扫描过程:
| 时间 | 变化 | 当前人数 |
|---|---|---|
| 1 | +1 | 1 |
| 2 | +1 | 2 |
| 4 | -1 | 1 |
| 5 | -1 | 0 |
| 7 | +1 | 1 |
| 9 | -1 | 0 |
最大值为 2。
三、差分数组 vs 扫描线
| 特性 | 差分数组 | 扫描线 |
|---|---|---|
| 典型用途 | 区间加减更新 | 区间重叠/统计 |
| 操作 | 用 diff[] 标记变化 | 用事件排序 |
| 时间复杂度 | O(n + q) | O(q log q) |
| 结果 | 修改后的数组 | 最大值、重叠次数等统计 |
| 思想联系 | 本质上都是“处理区间端点变化” | 只是实现方式不同 |
四、综合示例:区间覆盖次数
题目:
给出若干区间,输出每个位置被覆盖的次数。
输入:
区间:[1,3], [2,5], [4,6]
n = 7
差分写法
n = 7
intervals = [(1,3), (2,5), (4,6)]
diff = [0]*(n+2)
for l, r in intervals:
diff[l] += 1
diff[r+1] -= 1
cover = [0]*(n+1)
cover[0] = diff[0]
for i in range(1, n+1):
cover[i] = cover[i-1] + diff[i]
print(cover[1:]) # [1,2,2,2,1,1,0]
扫描线写法
events = []
for l, r in intervals:
events.append((l, 1))
events.append((r + 1, -1))
events.sort()
res = [0]*(n+1)
cur = 0
idx = 0
for i in range(1, n+1):
while idx < len(events) and events[idx][0] == i:
cur += events[idx][1]
idx += 1
res[i] = cur
print(res[1:]) # [1,2,2,2,1,1,0]
✅ 总结一句话:
- 差分数组:适合你知道数组长度、需要多次“区间加减”。
- 扫描线:适合你处理动态事件(区间开始/结束)、求最大重叠、覆盖长度等。
排队做实验
n=int(input())
a=list(map(int,input().split()))
t=[]
for i in range(n):
t.append([a[i],i+1])
t=sorted(t,key=lambda x:x[0])
s=0
q=[]
for i in range(n):
q.append(t[i][1])
s+=t[i][0]*(n-i-1)
s=s/n
print(" ".join(map(str,q)))
print("%0.2f" %s)
买卖股票的最佳时机
扫一遍,把历史最低价处理出来。每天卖掉的和历史最低价作差。
class Solution:
def maxProfit(self, prices: list[int]) -> int:
minm=[]
minm.append(prices[0])
for i in range(1,len(prices)):
minm.append(min(minm[i-1],prices[i]))
maxm=[]
maxm.append(prices[-1])
for i in range(1,len(prices)):
maxm.append(max(maxm[i-1],prices[-i-1]))
ans=0
for i in range(len(prices)-1):
ans=max(ans,maxm[len(prices)-i-2]-minm[i])
return ans
print(Solution().maxProfit([1,4,2]))
有多少种合法的出栈顺序
卡特兰数。一开始WA是因为没有用整除而是用了除,此时a的类型为小数,算到最后就爆了。
卡特兰数
from math import comb
n=int(input())
a=1
# if(n==1):
# print(1)
# else:
# print(comb(2*n,n)//(n+1))
for i in range(2,n+1):
a=(4*i-2)*a//(i+1)
print(a)
有效的括号
class Solution:
def isValid(self, s: str) -> bool:
def check(x,y):
if(x=='(' and y==')'):
return True
if(x=='[' and y==']'):
return True
if(x=='{' and y=='}'):
return True
return False
a=[]
flag=1
for i in range(len(s)):
if(s[i]=='(' or s[i]=='[' or s[i]=='{'):
a.append(s[i])
else:
if(len(a)==0):
flag=0
break
if(not check(a[-1],s[i])):
flag=0
break
a.pop()
if(len(a)!=0):
flag=0
if(flag==1):
return True
else:
return False
2025.10.14
军备竞赛
p=int(input())
a=list(map(int,input().split()))
a.sort()
k=0
q=len(a)-1
ans=0
while(q>=k):
if(p>=a[k]):
p-=a[k]
k+=1
else:
x1=k
x2=len(a)-1-q
if(x2>=x1):
break
else:
p+=a[q]
q-=1
ans=max(ans,k-len(a)+1+q)
# print(k,q,p,ans)
print(ans)
岛屿周长
dx=[-1,0,1,0]
dy=[0,1,0,-1]
ans=0
n,m=map(int,input().split())
vis=[[0 for _ in range(m+2)]for _ in range(n+2)]
def dfs(x,y):
global ans
flag=0
for i in range(4):
if(a[x+dx[i]][y+dy[i]]==1):
flag+=1
ans+=(4-flag)
for i in range(4):
if(a[x+dx[i]][y+dy[i]]==1 and vis[x+dx[i]][y+dy[i]]==0):
vis[x+dx[i]][y+dy[i]]=1
dfs(x+dx[i],y+dy[i])
#vis[x+dx[i]][y+dy[i]] = 0
a=[]
a.append([0]*(m+2))
for i in range(n):
l=list(map(int,input().split()))
l.insert(0,0)
l.append(0)
a.append(l)
a.append([0]*(m+2))
for i in range(n+2):
for j in range(m+2):
if(a[i][j]==1):
break
if(a[i][j]==1):
break
vis[i][j]=1
dfs(i,j)
print(ans)
计算鞍点
a=[]
maxm=[]#[0-n-1][idx]
minm=[]#[idx][0-n-1]
for i in range(5):
t=list(map(int,input().split()))
a.append(t)
maxm.append(t.index(max(t)))
for i in range(5):
t=float("inf")
idx=-1
for j in range(5):
if(a[j][i]<t):
idx=j
t=a[j][i]
minm.append(idx)
flag=0
for i in range(5):
if(minm[maxm[i]]==i):
flag=1
print(i+1,maxm[i]+1,a[i][maxm[i]])
if(flag==0):
print("not found")
Woodcutters
贪心。左右两端必取,然后考察每两棵树之间的段。这段空地只需要考虑左树向右倒和右树向左倒的情况,因为其他情况必然会跨越树桩。
n=int(input())
a=[]
b=[]
tree=[]
for i in range(n):
x,y=map(int,input().split())
a.append(x)
b.append(y)
tree.append([x-y,x])
tree.append([x,x+y])
ans=1
check=[0]*n
check[0]=1
for i in range(1,n):
l = a[i] - a[i - 1]
if(check[i-1]==0):
if(b[i-1]+b[i]<l):
check[i-1]=check[i]=1
ans+=2
elif(b[i-1]<l):
check[i-1]=1
ans+=1
elif(b[i]<l):
check[i]=1
ans+=1
else:
if(b[i]<l):
check[i]=1
ans+=1
if(check[n-1]==0):
ans+=1
print(ans)
Potions (Easy Version)
后悔解法。
维护一个小根堆。不管怎样先把药水喝了,如果健康值为负值就把堆顶的药水依次吐出来。
若dp则记录喝i瓶水的剩余生命值。
import heapq
n=int(input())
a=list(map(int,input().split()))
t=[]
sum=0
heapq.heapify(t)
for i in range(n):
sum+=a[i]
heapq.heappush(t,a[i])
while(sum<0 and len(t)>0):
x=heapq.heappop(t)
sum-=x
print(len(t))
最大最小整数
冒泡排序。
提示 位数不同但前几位相同的时候。例如: 898 8987,大整数是898+8987,而不是8987+898。
因此重复每一位自身使所有数长度相同亦可。
n=int(input())
a=list(map(str,input().split()))
for i in range(n):
for j in range(i+1,n):
if(a[i]+a[j]<a[j]+a[i]):
a[i],a[j]=a[j],a[i]
print("".join(a),end=" ")
for i in range(n):
for j in range(i+1,n):
if(a[i]+a[j]>a[j]+a[i]):
a[i],a[j]=a[j],a[i]
print("".join(a))
因材施教
对差分数组排序。可以证明取数组中的m-n个值和分组一一对应,因此取最小的m-n个即可。
n,m=map(int,input().split())
a=list(map(int,input().split()))
a.sort()
dif=[]
for i in range(n-1):
dif.append(a[i+1]-a[i])
dif.sort()
ans=0
for i in range(n-m):
ans+=dif[i]
print(ans)
Light It Up
计算ans:添加处及之前的奇数项,加上添加处之后的(本来的)偶数项,再减去添加处与本来开灯的时间点相差的1个时间单位。
被greedy的tag骗了。
n,m=map(int,input().split())
a=list(map(int,input().split()))
a.append(m)
a.insert(0,0)
ans=0
dif=[]
pre_odd=[]
pre_even=[]
for i in range(n+1):
dif.append(a[i+1]-a[i])
pre_odd.append(0)
pre_odd.append(dif[1])
pre_even.append(dif[0])
for i in range(2,n+1):
if(i%2==0):
pre_even.append(pre_even[i//2-1]+dif[i])
else:
pre_odd.append(pre_odd[i//2]+dif[i])
ans=pre_even[-1]
for i in range(1,n+1,2):
ans=max(ans,pre_even[(i-1)//2]+pre_odd[-1]-pre_odd[i//2]-1)
print(ans)
XXXXX

t=int(input())
for i in range(t):
n,m=map(int,input().split())
a=list(map(int,input().split()))
res=sum(a)
ans=n
if(res%m!=0):
print(n)
else:
flag=0
idx=0
while(res%m==0 and idx<n):
res-=a[idx]
idx+=1
if(res%m!=0):
flag=1
ans=min(ans,idx)
res=sum(a)
idx=n-1
while(res%m==0 and idx>=0):
res-=a[idx]
idx-=1
if(res%m!=0):
flag=1
ans=min(ans,n-1-idx)
if(flag==0):
print(-1)
else:
print(n-ans)
2025.10.16
生存游戏
保护圈。
n,m=map(int,input().split())
a=[]
a.append([0]*(m+2))
for i in range(n):
l=list(map(int,input().split()))
l.insert(0,0)
l.append(0)
a.append(l)
a.append([0]*(m+2))
b=[[0 for _ in range(m+2)]for _ in range(n+2)]
for i in range(1,n+1):
for j in range(1,m+1):
cnt=a[i-1][j-1]+a[i-1][j]+a[i-1][j+1]+a[i][j-1]+a[i][j+1]+a[i+1][j-1]+a[i+1][j]+a[i+1][j+1]
if(a[i][j]==1):
if(cnt<2 or cnt>3):
b[i][j]=0
else:
b[i][j]=1
else:
if(cnt==3):
b[i][j]=1
for i in range(1,n+1):
for j in range(1,m):
print(b[i][j],end=" ")
print(b[i][m])
完美立方
直接开三次根再取整会产生进度问题。预存每个数的三次方。枚举三个加和的数避免重复运算。
n=int(input())
res=[]
a=set()
for i in range(101):
a.add(i*i*i)
for i in range(2,n):
for j in range(i,n):
for k in range(j,n):
t=i**3+j**3+k**3
if(t>n**3):
continue
if(t in a):
res.append([round(t**(1/3)),i,j,k])
res.sort()
for i in range(len(res)):
print("Cube = %d, Triple = (%d,%d,%d)" %(res[i][0],res[i][1],res[i][2],res[i][3]))
序列合并
双指针。
n,m=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
i=0
j=0
res=[]
while(i<n and j<m):
if(a[i]<=b[j]):
res.append(a[i])
i+=1
else:
res.append(b[j])
j+=1
res.extend(a[i:n])
res.extend(b[j:m])
print(" ".join(map(str,res)))
判断八皇后
a=[]
for i in range(8):
t=list(map(int,input().split()))
a.append(t)
x=set()
y=set()
z=set()
w=set()
flag=1
for i in range(8):
temp=sum(a[i])
if(temp!=1):
flag=0
break
for j in range(8):
if(a[i][j]==1):
x.add(i)
y.add(j)
z.add(i+j)
w.add(i-j)
if(len(y)!=8 or len(z)!=8 or len(w)!=8 or flag==0):
print("NO")
else:
print("YES")
一一相依
双指针。
n,k=map(int,input().split())
s=input()
pre=[]
pre.append(int(s[0]))
for i in range(1,n):
pre.append(pre[i-1]+int(s[i]))
i=0
j=0
ans=0
while(j<n):
if(i==0):
cnt=(j-i+1)-pre[j]
else:
cnt=(j-i+1)-(pre[j]-pre[i-1])
if(cnt<=k):
ans=max(ans,j-i+1)
j+=1
else:
i+=1
print(ans)
2025.10.19
图的拉普拉斯矩阵
n,m=map(int,input().split())
d=[[0 for _ in range(n)]for _ in range(n)]
a=[[0 for _ in range(n)]for _ in range(n)]
for i in range(m):
x,y=map(int,input().split())
d[x][x]+=1
d[y][y]+=1
a[x][y]=1
a[y][x]=1
for i in range(n):
lst=[]
for j in range(n):
lst.append(d[i][j]-a[i][j])
print(" ".join(map(str,lst)))
Same Differences
dict、defaultdict的时间复杂度均为O(1).

Complexity of Python Operations
from collections import defaultdict
t=int(input())
for i in range(t):
n=int(input())
a=list(map(int,input().split()))
ans=0
b=defaultdict(int)
#b=[0]*(200005)
for j in range(n):
t=a[j]-j
b[t]+=1
for j in b.values():
if(j==1):
continue
ans+=j*(j-1)//2
print(ans)
Saruman's Army
两个while循环,一个找开始的点,另一个找放置点。找完一轮之后开始新的一轮。
while(True):
r,n=map(int,input().split())
if(r==-1 and n==-1):
break
a=list(map(int,input().split()))
a.sort()
i=0
ans=0
while(i<n):
start=a[i]
i+=1
while(i<n and a[i]<=start+r):
i+=1
cur=a[i-1]
while(i<n and a[i]<=cur+r):
i+=1
ans+=1
print(ans)
2025.10.21
垃圾炸弹
在接收数据时更新每个点处放置炸弹时可以清除的垃圾数。在range()中使用min()、max()以避免分类讨论。注意边界处的方形边长可以小于2d。
d=int(input())
n=int(input())
a=[[0 for _ in range(1030)]for _ in range(1030)]
for i in range(n):
x,y,z=map(int,input().split())
for j in range(max(0,x-d),min(1024,x+d)+1):
for k in range(max(0,y-d),min(1024,y+d)+1):
a[j][k]+=z
res=0
ans=0
for i in range(1025):
for j in range(1025):
if(a[i][j]>ans):
res=1
ans=a[i][j]
elif(a[i][j]==ans):
res+=1
print(res,ans)
约瑟夫问题
使用递推公式或使用队列模拟。递推公式为i=(i+m-1)%总人数.
模拟先全部进队,再依次从头部取出并放回尾部,由此形成一个环。
队列的遍历就是拿出再放回。
from collections import deque
while(True):
n,m=map(int,input().split())
if(n==0 and m==0):
break
a=deque()
for i in range(1,n+1):
a.append(i)
while(len(a)>1):
for i in range(m-1):
a.append(a.popleft())
a.popleft()
print(a.popleft())
摆动序列
考虑转折次数。开一个旗帜变量记录上一次是向上还是向下。如果发生转折就答案+1。最后的序列长度即为转折次数+1.注意开头结尾,以及如果中间一段是平的也算一次转折。
n=int(input())
nums=list(map(int,input().split()))
dir=0
ans=0
for i in range(1,n):
if(nums[i]>nums[i-1]):
if(dir==1):
continue
ans+=1
dir=1
elif(nums[i]<nums[i-1]):
if(dir==-1):
continue
ans+=1
dir=-1
print(ans+1)
分发糖果
考虑连续上升子序列,此时会对子序列中的每一个人有约束。但是从左往右扫的时候无法以O(n)的复杂度判断下降子序列。因此从右往左再扫一遍。left,right数组分别记录扫描过程中要求的最少糖果数,初值置1.最后每个人的最少糖果数即为两数组中记录的较大值,此时一定满足条件。
n=int(input())
ratings=list(map(int,input().split()))
idx=0
ans=0
left=[1]*n
right=[1]*n
for i in range(1,n):
if(ratings[i]>ratings[i-1]):
left[i]=left[i-1]+1
for i in range(n-2,-1,-1):
if(ratings[i]>ratings[i+1]):
right[i]=right[i+1]+1
for i in range(n):
ans+=max(left[i],right[i])
print(ans)
2025.10.25
Fill in the Matrix
考虑m×m的矩阵,首行为0-(m-1),之后每一行依次向右移动一位。此时每一列都包含了0-(m-1)所有的数。删除一行,所有列的MEX值即为0-(m-1),此时数列的美丽值最大。而当n<m-1时,直接取前面构造的n行,所有列的MEX值可以取遍0-n,此时数列的美丽值为n+1.注意特判一列的情况,此时美丽值为1.
# 012
# 120
# 012
# n行m列
# n>=m-1:m
# n<m-1:n+1
# 0123456
# 1234560
# 2345601
t=int(input())
for i in range(t):
n,m=map(int,input().split())
if(m==1):
print(0)
for i in range(n):
print(0)
elif(n>=m-1):
print(m)
for j in range(m-1):
lst=[]
for k in range(m):
lst.append((j+k)%m)
print(" ".join(map(str,lst)))
for j in range(n-m+1):
lst=[]
for k in range(m):
lst.append(k)
print(" ".join(map(str,lst)))
else:
print(n+1)
for j in range(n):
lst=[]
for k in range(m):
lst.append((j+k)%m)
print(" ".join(map(str,lst)))
神奇的幻方
n=int(input())
n=n*2-1
a=[[0 for _ in range(n)]for _ in range(n)]
if(n==1):
print(1)
else:
x=0
y=n//2
for i in range(1,n*n+1):
a[x][y]=i
if(x==0 and y==n-1):
x=x+1
elif(x==0):
x=n-1
y=y+1
elif(y==n-1):
y=0
x=x-1
elif(a[x-1][y+1]!=0):
x=x+1
else:
x=x-1
y=y+1
for i in range(n):
for j in range(n-1):
print(a[i][j],end=" ")
print(a[i][n-1])
2025.10.27
世界杯只因
求完全覆盖区间的最小子区间数。按区间开头排序,往后一直搜到留下空隙的子区间之前,取这些子区间中结尾最大的。
用二维数组会超内存,可以用数组套元组。
n=int(input())
a=list(map(int,input().split()))
lst=[]
for i in range(n):
x=max(1,i+1-a[i])
y=min(n,i+1+a[i])
lst.append((x,y))
lst.sort()
right=0
idx=0
ans=0
while(right<n):
maxr=right
while(idx<n and lst[idx][0]<=right+1):
maxr=max(maxr,lst[idx][1])
idx+=1
right=maxr
ans+=1
print(ans)
【深基7.例4】歌唱比赛
n,m=map(int,input().split())
a=[]
for i in range(n):
lst=list(map(int,input().split()))
lst.sort()
s=sum(lst)-lst[0]-lst[-1]
a.append(s)
print("%0.2f" %(max(a)/(m-2)))
后序表达式求值
n=int(input())
for i in range(n):
t=list(input().split())
a=[]
for j in t:
if(j=='+'):
y=a.pop()
x=a.pop()
a.append(x+y)
elif(j=='-'):
y=a.pop()
x=a.pop()
a.append(x-y)
elif(j=='*'):
y=a.pop()
x=a.pop()
a.append(x*y)
elif(j=='/'):
y=a.pop()
x=a.pop()
a.append(x/y)
else:
a.append(float(j))
print("%0.2f" %(a.pop()))
Bomb Game
a,b,k=map(int,input().split())
m=[[1 for _ in range(b)]for _ in range(a)]
for i in range(k):
r,s,p,t=map(int,input().split())
r-=1
s-=1
p//=2
if(t==0):
for j in range(max(0,r-p),min(a-1,r+p)+1):
for w in range(max(0,s-p),min(b-1,s+p)+1):
m[j][w]=t
elif(t==1):
for j in range(a):
for w in range(b):
if(max(0,r-p)<=j<=min(a-1,r+p) and max(0,s-p)<=w<=min(b-1,s+p)):
continue
else:
m[j][w]=0
ans=0
for i in range(a):
for j in range(b):
if(m[i][j]==1):
ans+=1
print(ans)
上机考试
m,n=map(int,input().split())
a=[]
b=[]
s=[]
a.append([-1]*(n+2))
for i in range(m):
lst=list(map(int,input().split()))
lst.insert(0,-1)
lst.append(-1)
a.append(lst)
a.append([-1]*(n+2))
for i in range(m*n):
lst=list(map(int,input().split()))
b.append(sum(lst))
if(len(lst)==0):
s.append(-1)
else:
temp=0
for j in lst:
temp+=j
temp<<=1
s.append(temp)
c=sorted(b)
c=c[::-1]
t=int(m*n*0.4)
ans=0
if(t>0):
score=c[t-1]
if(c[t]==score):
for i in range(t):
if(c[i]>score):
ans+=1
else:
break
else:
ans=t
res=0
dx=[-1,0,1,0]
dy=[0,1,0,-1]
for i in range(1,m+1):
for j in range(1,n+1):
for k in range(4):
x=i+dx[k]
y=j+dy[k]
if(a[x][y]==-1):
continue
else:
if(s[a[i][j]]==s[a[x][y]]):
res+=1
break
print(res,ans)
螺旋矩阵
两个数组分别记录上下左右四个方向,dir记录具体的方向。
n=int(input())
a=[[0 for _ in range(n)]for _ in range(n)]
dir=0
x=0
y=0
dy=[1,0,-1,0]
dx=[0,1,0,-1]
for i in range(1,n*n+1):
a[x][y]=i
x0=x+dx[dir]
y0=y+dy[dir]
if(x0<0 or x0>=n or y0<0 or y0>=n or a[x0][y0]!=0):
dir=(dir+1)%4
x0=x+dx[dir]
y0=y+dy[dir]
x=x0
y=y0
for i in range(n):
print(" ".join(map(str,a[i])))
斐波拉契数列-大数据版
P1962 斐波那契数列 题解
矩阵乘法+矩阵快速幂。
mod=10**9+7
def mul(x,y,p,q,r):
qaq=[[0 for _ in range(q)]for _ in range(p)]
for i in range(p):
for j in range(q):
for k in range(r):
qaq[i][j]+=x[i][k]*y[k][j]%mod
qaq[i][j]%=mod
return qaq
def quick_power(x,n):
t=[[1,0],[0,1]]
while(n):
if(n&1):
t=mul(t,x,2,2,2)
x=mul(x,x,2,2,2)
n>>=1
return t
n=int(input())
a=[[1,1]]
base=[[1,1],[1,0]]
if(n==1):
print(1)
else:
ans=mul(a,quick_power(base,n-2),1,2,2)
print(ans[0][0])
【模板】矩阵快速幂
mod=10**9+7
def mul(x,y,p,q,r):
qaq=[[0 for _ in range(q)]for _ in range(p)]
for i in range(p):
for j in range(q):
for k in range(r):
qaq[i][j]+=x[i][k]*y[k][j]%mod
qaq[i][j]%=mod
return qaq
def quick_power(x,k):
global n
t=[[0 for _ in range(n)]for _ in range(n)]
for i in range(n):
t[i][i]=1
while(k):
if(k&1):
t=mul(t,x,n,n,n)
x=mul(x,x,n,n,n)
k>>=1
return t
n,k=map(int,input().split())
a=[]
for i in range(n):
lst=list(map(int,input().split()))
a.append(lst)
ans=quick_power(a,k)
for i in range(n):
print(" ".join(map(str,ans[i])))
汉诺塔问题(Tower of Hanoi)
递归。
def hanoi(x,a,b,c):
if(x==0):
return
hanoi(x-1,a,c,b)
print("%d:%s->%s" %(x,a,c))
hanoi(x-1,b,a,c)
n,a,b,c=input().split()
n=int(n)
hanoi(n,a,b,c)
2025.10.28
晶矿的个数
对每个点dfs,如果搜索过就标记。开始搜索的次数就是晶矿的个数。
k=int(input())
dx=[0,1,0,-1]
dy=[1,0,-1,0]
def dfs(x,y,val):
for i in range(4):
x0=x+dx[i]
y0=y+dy[i]
if(0<=x0<n and 0<=y0<n):
if(a[x0][y0]==val and vis[x0][y0]==0):
vis[x0][y0]=1
dfs(x0,y0,val)
for temp in range(k):
n=int(input())
a=[]
for i in range(n):
lst=input()
a.append(lst)
vis=[[0 for _ in range(n)]for _ in range(n)]
ansr=0
ansb=0
for i in range(n):
for j in range(n):
if(vis[i][j]==1):
continue
if(a[i][j]=='r'):
vis[i][j]=1
dfs(i,j,a[i][j])
ansr+=1
elif(a[i][j]=='b'):
vis[i][j]=1
dfs(i,j,a[i][j])
ansb+=1
print(ansr,ansb)
岛屿数量
class Solution:
def numIslands(self, grid: list[list[str]]) -> int:
m=len(grid)
n=len(grid[0])
vis=[[0 for _ in range(n)]for _ in range(m)]
dx=[1,0,-1,0]
dy=[0,-1,0,1]
def dfs(x,y):
for i in range(4):
x0=x+dx[i]
y0=y+dy[i]
if(0<=x0<m and 0<=y0<n and vis[x0][y0]==0 and grid[x0][y0]=='1'):
vis[x0][y0]=1
dfs(x0,y0)
ans=0
for i in range(m):
for j in range(n):
if(vis[i][j]==0 and grid[i][j]=='1'):
dfs(i,j)
ans+=1
return ans
print(Solution().numIslands([["1","1","1","1","0"],["1","1","0","1","0"],["1","1","0","0","0"],["0","0","0","0","0"]]))
print(Solution().numIslands([["1","1","0","0","0"],["1","1","0","0","0"],["0","0","1","0","0"],["0","0","0","1","1"]]))
Strange Towers of Hanoi
三阶汉诺塔的次数为\(2^n-1\).根据题目提示计算即可。
oeis-A007664
类似递推可得n个圆盘时m阶Hanoi塔的最小移动次数。Frame-Stewart algorithm:
\(T(m,n)=\mathop{min}\limits_{1 \leq r<n}(2T(m,n-r)+T(m-1,r))\)
多柱汉诺塔的Frame-Stewart算法
def hanoi3(n):
return 2**n-1
def hanoi4(n):
if(n==1):
return 1
ans=float("inf")
for i in range(1,n):
ans=min(ans,hanoi4(n-i)+hanoi3(i)+hanoi4(n-i))
return ans
for i in range(1,13):
print(hanoi4(i))
全排列
注意数组复制的浅拷贝问题。arr=arr1.copy()可以深拷贝。
class Solution:
def permute(self, nums: list[int]) -> list[list[int]]:
vis=[0]*len(nums)
ans=[]
def dfs(step,res):
if(step==len(nums)):
ans.append(res)
return
for i in range(len(nums)):
if(vis[i]==0):
vis[i]=1
temp=res.copy()
temp.append(nums[i])
dfs(step+1,temp)
vis[i]=0
dfs(0,[])
return ans
print(Solution().permute([1,2,3]))
print(Solution().permute([0,1]))
print(Solution().permute([1]))
Gold Rush
注意递归调用函数的时候函数的返回值类型是什么。
t=int(input())
def dfs(lst,m):
if(m in lst):
return True
flag=0
for i in lst:
if(i%3==0):
flag=1
qaq=lst.copy()
qaq.remove(i)
qaq.add(i//3)
qaq.add(i//3*2)
return dfs(qaq,m)
if(flag==0):
return False
for i in range(t):
n,m=map(int,input().split())
if(n==m):
print("YES")
elif(n<m):
print("NO")
else:
lst=set()
lst.add(n)
if(dfs(lst,m)):
print("YES")
else:
print("NO")
子集
使用二进制存储是否选取某元素。
class Solution:
def subsets(self, nums: list[int]) -> list[list[int]]:
n=len(nums)
ans=[]
for i in range(1<<n):
res=[]
for j in range(n):
if(i&1<<j):
res.append(nums[j])
ans.append(res)
return ans
print(Solution().subsets(([1,2,3])))
print(Solution().subsets(([0])))
2025.10.31
电话号码的字母组合
class Solution:
def letterCombinations(self, digits: str) -> list[str]:
tele = {2: ['a', 'b', 'c'], 3: ['d', 'e','f'],4:['g','h','i'],5:['j','k','l'],6:['m','n','o'],7:['p','q','r','s'],8:['t','u','v'],9:['w','x','y','z']}
res=[]
def dfs(step,ans):
if(step==len(digits)):
res.append(ans)
return
for i in tele[int(digits[step])]:
dfs(step+1,ans+i)
dfs(0,"")
return res
print(Solution().letterCombinations("23"))
print(Solution().letterCombinations("2"))
组合总和
class Solution:
def combinationSum(self, candidates: list[int], target: int) -> list[list[int]]:
ans=[]
def dfs(sum,res,cur):
if(sum==target):
temp=res.copy()
ans.append(res)
return
for i in range(cur,len(candidates)):
if(sum+candidates[i]<=target):
temp=res.copy()
temp.append(candidates[i])
dfs(sum+candidates[i],temp,i)
dfs(0,[],0)
return ans
print(Solution().combinationSum([2,3,6,7],7))
分割回文串
class Solution:
def partition(self, s: str) -> list[list[str]]:
def check(x):
if(x==x[::-1]):
return True
else:
return False
ans=[]
def dfs(cur,res):
if(cur==len(s)):
ans.append(res)
return
for i in range(cur,len(s)):
if(check(s[cur:i+1])):
temp=res.copy()
temp.append(s[cur:i+1])
dfs(i+1,temp)
dfs(0,[])
return ans
print(Solution().partition("aab"))

浙公网安备 33010602011771号