算 法

(题目持续更新,建议收藏)

语法基础:

日期问题:

https://www.lanqiao.cn/problems/614/learning/

python 复制代码
from datetime import *
print((date(2000, 5, 4) - date(2000, 1, 1)).days + 1)

https://www.lanqiao.cn/problems/611/learning/

python 复制代码
from datetime import *
t1 = date(1901,1,1)
t2 = date(2000,12,31)
res = 0
delta = timedelta(days = 1)# 时间步长
while t1 <= t2:
  if t1.weekday() == 0:# 星期一
    res += 1
  t1 += delta
print(res)

https://www.lanqiao.cn/problems/1038/learning/

python 复制代码
from datetime import *

t1 = date(1900, 1, 1)
t2 = date(9999, 12, 31)# 最大合法日期
delta = timedelta(days = 1)# 时间步长
res = 0
while t1 < t2:
    if '2' in ''.join([str(t1.year), str(t1.month), str(t1.day)]): # 拼成字符串
      res += 1
    t1 += delta
print(res + 1) # 1994240,加上最后一天的 2

https://www.luogu.com.cn/problem/P8651

python 复制代码
days = [0,31,28,31,30,31,30,31,31,30,31,30,31]
start = 1960
end = 2059
def is_leap_year(y):
    return (y % 4 == 0 and y % 100 != 0) or (y % 400 == 0)
a,b,c = map(int,input().split("/"))
for year in range(start,end+1):
    days[2] = 29 if is_leap_year(year) else 28
    for month in range(1,13):
        for day in range(1,days[month]+1):
            c1 = (a == year % 100 and b == month and c == day)
            c2 = (a == month and b == day and c == year % 100)
            c3 = (a == day and b == month and c == year % 100)
            if c1 or c2 or c3:
                print(f"{year}-{month:02d}-{day:02d}")

基础算法:

枚举:

https://www.lanqiao.cn/problems/21244/learning/

python 复制代码
ans = 0
for i in range(1,2026):
  for j in range(i+1,2026):
    k = j + j - i# 推第三个数
    if k <= 2025:
      ans += 1
print(ans*2) 

https://www.luogu.com.cn/problem/P12377

python 复制代码
# cnt = 0
# start = 12345678
# end = 98765432
# for num in range(start,end+1):
#     s = str(num)
#     i1 = s.find('2')
#     if i1 == -1:
#         continue
#     i2 = s.find('0',i1+1)
#     if i2 == -1:
#         continue
#     i3 = s.find('2',i2+1)
#     if i3 == -1:
#         continue
#     i4 = s.find('3',i3+1)
#     if i4 != -1:
#         cnt += 1
# total = end-start+1
# print(total-cnt)
print(85959030)

https://www.luogu.com.cn/problem/P8641

python 复制代码
n = int(input())
nums = list(map(int,input().split()))
res = 0
for i in range(n):# 起始索引
    cnt,j = 0,i# 计数器 当前卡片索引
    cur = nums.copy()
    c = 0# 当前总和
    while cur:
        cnt += 1
        if cnt > max(cur):
            break
        if cnt == cur[j]:
            c += cur[j]
            del cur[j]
            cnt = 0
            if not cur:
                break
            if j == len(cur):# 拿走的是最后一个
                j = 0
        else:
            j += 1
            if j >= len(cur):
                j = 0
    res = max(res,c)
print(res)

https://www.luogu.com.cn/problem/P8635

python 复制代码
import math
n = int(input())
max_a = int(math.sqrt(n))
for a in range(max_a+1):
    a_sq = a*a
    if 4 * a_sq > n:# a*a + a*a + a*a + a*a > n 时无需继续
        break
    max_b = int(math.sqrt(n - a_sq))
    for b in range(a,max_b+1):
        b_sq = b*b
        ab_sq = a_sq + b_sq
        if ab_sq + 2 * b*b > n:# b*b + b*b > 剩余值
            break
        max_c = int(math.sqrt(n - ab_sq))
        for c in range(b,max_c+1):
            c_sq = c*c
            abc_sq = ab_sq + c_sq
            d_sq = n - abc_sq
            d = int(math.sqrt(d_sq))
            if d*d == d_sq and d >= c:# d 是整数且 d >= c
                print(a,b,c,d)
                exit()

https://www.luogu.com.cn/problem/P8781

python 复制代码
N = int(input())
for i in range(1, N+1):
    print(2 * max(i-1, N-i))# 每棵灌木的最大高度等于它两次被修剪之间的最大间隔天数

构造:

https://ac.nowcoder.com/acm/problem/280752

python 复制代码
a = int(input())
if a == 0:
    for _ in range(3):
        print('1 1 1')
else:
    print(f'{a} 1 2')
    print('3 2 1')
    print('1 1 1')
# D = a11A11 + a12A12 + a13A13
# Aij = (-1)^(i+j) * Mij

https://ac.nowcoder.com/acm/problem/286330

python 复制代码
import sys
input = lambda:sys.stdin.readline().strip()# 高效读取输入
n,m,k = map(int,input().split())
max_dim = max(n,m)
if k < max_dim:
  print(-1)
else:
  grid = [[0] * m for _ in range(n)]
  count = 0
  # 填充对角线
  for i in range(max_dim):
    r = i % n# 取余不越界
    c = i % m
    grid[r][c] = 1
    count += 1
  # 剩余球数
  grid[0][0] += (k - count)
  for i in grid:
    print(' '.join(map(str,i)))

https://ac.nowcoder.com/acm/problem/261524

python 复制代码
import math
for _ in range(int(input())):
    n, k = map(int, input().split())
    # 让每一枚硬币都被反转奇数次才能成
    if k % 2 == 1:# k是奇数
      print(n)
      # 逐个位置翻转
      for i in range(1,n+1):
        print(i,end = " ")
    else:# k是偶数
      d = math.gcd(n,k)# n个硬币分成d个子环
      if (k // d) % 2 == 0:# 每次反转k个硬币等价于每个子环里反转k//d个硬币
        print(-1)# 为偶数不能成
      else:
        print(n // d)
        for i in range(1,n+1,d):
          print(i,end = " ")
    print()

https://ac.nowcoder.com/acm/problem/284002

python 复制代码
n = int(input())
arr = [set() for _ in range(n)]
k = 1
for i in range(n):# 当前集合
  for j in range(i,n):# 其他集合
    if i == j:
      arr[i].add(k)
    else:# 给其他集合分配一个相同元素
      arr[i].add(k)
      arr[j].add(k)
    k += 1
for s in arr:
  print(' '.join([str(x) for x in s]))

模拟:

https://ac.nowcoder.com/acm/problem/279308

python 复制代码
a,b = input().split()
if "." in a:# 小数补0
    a += "000000"
else :
    a += ".000000"
if "." in b:
    b += "000000"
else :
    b += ".000000"
a = a.split(".")
b = b.split(".")
if a[0] == b[0] and a[1][:6] == b[1][:6]:# 整数部分和小数部分前6位
    print("YES")
else:
    print("NO")

https://ac.nowcoder.com/acm/problem/246909

python 复制代码
for _ in range(int(input())):
    n=int(input())
    h=list(map(int,input().split()))
    a,k,b=map(int,input().split())
    m=int(input())
    for _ in range(m-1):
      h=[i+a if i+a<=k else b for i in h]
    print(*h)# 解包列表,空格分隔输出

https://ac.nowcoder.com/acm/problem/52069

python 复制代码
n, m = map(int, input().split())
grid = [input().strip() for _ in range(n)]
for i in range(n):
    res = []
    for j in range(m):
        if grid[i][j] == '*':
            res.append('*')
        else:
            count = 0
            for dx in (-1, 0, 1):
                for dy in (-1, 0, 1):
                    if dx == 0 and dy == 0:
                        continue
                    x = i + dx
                    y = j + dy
                    if 0 <= x < n and 0 <= y < m:
                        if grid[x][y] == '*':
                            count += 1
            res.append(str(count))
    print(''.join(res))

https://ac.nowcoder.com/acm/problem/17361

python 复制代码
n = int(input())
nums = list(map(int, input().split()))
if n <= 2:
    print(0)
else:
    cnt = 0
    in_up = False# 是否上升
    for i in range(1, n):
        pre = nums[i-1]
        cur = nums[i]
        if pre < cur:
            in_up = True
        elif pre > cur:
            if in_up:
                cnt += 1
                in_up = False
        else:
            pass
    print(cnt)

https://www.luogu.com.cn/problem/P10899

python 复制代码
res = 0
cur = 0
p = None
while True:
    try:
        s = input().strip()
        s_l = s.split()
        if s_l[0] == s_l[1]:
            if p == None:
                cur = 1
            else:
                if int(s_l[2]) - p <= 1000:
                    cur += 1
                else:
                    cur = 1
            res = max(cur,res)
            p = int(s_l[2])
        else:
            cur = 0
            p = None
    except EOFError:
        break
print(res)

字符串:

https://ac.nowcoder.com/acm/problem/287368

python 复制代码
from collections import Counter
s = str(input())
n = len(s) // 2
s1 = s[:n]
s2 = s[n:]
m1 = n - max(Counter(s1).values())
m2 = n - max(Counter(s2).values())
num = m1 + m2
print(num)

https://ac.nowcoder.com/acm/problem/254201

python 复制代码
s = input()
t = input()
k = s + s
ans = 0
for i in range(len(s)):
  if k[i:i+len(t)] == t:
    ans += 1
print(ans)

https://ac.nowcoder.com/acm/problem/230720

python 复制代码
def f(s):
    n = len(s)
    for i in range(n-1):
        if s[i] == s[i+1]:
            return 2
    for i in range(n-2):
        if s[i] == s[i+2]:
            return 3
    return -1
s = input().strip()
print(f(s))

思维:

https://ac.nowcoder.com/acm/problem/286349

python 复制代码
l,r=map(int,input().split())
print(r//2-(l-1)//2)# 1~r的偶数个数 - 1~l-1的偶数个数

https://ac.nowcoder.com/acm/problem/281330

python 复制代码
import math
x = int(input())
print(x)
print(f"={x}^1")
e = int(math.log2(x))# 指数上限
for i in range(2,e+1):
    a = round(x**(1/i))
    if a**i == x:# 防止误差
        print(f"={a}^{i}")

https://ac.nowcoder.com/acm/problem/259237

python 复制代码
a,k,q = map(int, input().split())
for _ in range(q):
    l,r = map(int, input().split())
    # 公差k为偶数,首项a为偶数
    if a % 2 == 0 and k % 2 == 0:
        print(-1)  # 所有项都是偶数
    
    # 公差k为偶数,首项a为奇数
    elif a % 2 == 1 and k % 2 == 0:
        print(1)   # 所有项都是奇数
    
    # 公差k为奇数,奇偶性交替
    else:
        # 区间长度为偶数,奇偶数量相等
        if (r - l + 1) % 2 == 0:
            print(0)
        # 区间长度为奇数,由第一个数A_l的奇偶性决定
        else: 
            if (a + (l - 1)*k) % 2 == 0:
                print(-1)  # A_l为偶数,偶数多1个
            else:
                print(1)   # A_l为奇数,奇数多1个

https://ac.nowcoder.com/acm/problem/255189

python 复制代码
x = int(input())
x = x*10
x = x + (7 - x % 7)# 补数
print(x)

https://ac.nowcoder.com/acm/problem/209794

python 复制代码
# 均值不等式 a+b+c >= 3 * (a*b*c)^(1/3) 当a=b=c时
n = int(input())
m = n**(1/3)
res = 3 * m
print("{:.3f}".format(res))

https://ac.nowcoder.com/acm/problem/287930

python 复制代码
from collections import defaultdict
n,m = map(int,input().split())
rows = [input() for _ in range(n)]
# col_patterns = [''.join(rows[i][j] for i in range(n)) for j in range(m)]
col_patterns = [''.join(col) for col in zip(*rows)]#每一列
# cnt = Counter(res) 
cnt = defaultdict(int)# 初始化字典
for col in col_patterns:
  cnt[col] += 1
print(max(cnt.values()))

排序:

https://leetcode.cn/problems/queue-reconstruction-by-height

python 复制代码
class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort(key=lambda x: (-x[0], x[1]))# 按身高降序,相同按k升序
        res = []
        for p in people:
            res.insert(p[1], p)
        return res

二分:

https://www.luogu.com.cn/problem/P2249

python 复制代码
import bisect
n,m = map(int,input().split())
nums = list(map(int,input().split()))
s = set(nums)
Q = list(map(int,input().split()))
for q in Q:
    if q not in s:
        print("-1",end=" ")
    else:
        # 将"大于等于 x"转化成"大于 x-1"
        print(bisect.bisect(nums,q-1)+1,end=" ")

https://leetcode.cn/problems/count-the-number-of-fair-pairs

python 复制代码
class Solution:
    def countFairPairs(self, nums: List[int], lower: int, upper: int) -> int:
        nums.sort()
        ans = 0
        n = len(nums)
        for i,x in enumerate(nums):
            # 查找范围:j > i,且 lower <= x + nums[j] <= upper
            # 即 lower - x <= nums[j] <= upper - x
            l = bisect_left(nums,lower-x,i+1,n)
            r = bisect_right(nums,upper-x,i+1,n)
            ans += r - l
        return ans

https://www.lanqiao.cn/problems/3510/learning/

python 复制代码
n = int(input())
l = [list(map(int,input().split())) for _ in range(n)]
def check(x):
  for i in l:
    if (i[0] // x) != i[1]:
      if (i[0] // x) > i[1]:
        return 1
      else:
        return -1
  return 0
left = 1
right = max(max(l))
while left <= right:
  mid = (left+right)//2
  res = check(mid)
  if res == 1: # 商偏大 → x偏小,需要增大x
    left = mid + 1 
  else:
    if res == 0:
      mn = mid
    right = mid -1
left = 1
right = max(max(l))
while left <= right:
  mid = (left+right)//2
  res = check(mid)
  if res == -1: # 商偏小 → x偏大,需要减小x
    right = mid - 1 
  else:
    if res == 0:
      mx = mid
    left = mid + 1
print(mn,mx)

https://leetcode.cn/problems/maximum-candies-allocated-to-k-children/description

python 复制代码
class Solution:
    def maximumCandies(self, candies: List[int], k: int) -> int:
        if sum(candies) < k:
            return 0
        def check(res):
            return sum(i // res for i in candies) >= k
        lo,hi = 1,max(candies)+1
        while lo < hi:
            mid = (lo + hi) >> 1
            if check(mid):# 能分mid个,尝试更大的数
                lo = mid + 1
            else:#尝试更小的数
                hi = mid
        return lo - 1
        # lo,hi = 1,max(candies) 
        # while lo <= hi:
        #     mid = lo + (hi - lo) // 2
        #     if check(mid):
        #         lo = mid + 1
        #     else:
        #         hi = mid - 1
        # return hi

前缀和:

https://www.luogu.com.cn/problem/P8218

python 复制代码
n = int(input())
a = list(map(int,input().split()))
p = [0] * (n+1)
for i in range(n):
    p[i+1] = p[i] + a[i]
for _ in range(int(input())):
    l,r = map(int,input().split())
    print(p[r]-p[l-1])

https://ac.nowcoder.com/acm/problem/288177

python 复制代码
n = int(input())
s = input()
a = [1 if char == '1' else -1 for char in s]
pre_sum = [0] * (n+1)
for i in range(1,n+1):# 前缀和数组
  pre_sum[i] = pre_sum[i-1] + a[i-1]
min_pre = min(pre_sum[1:])
if min_pre >= 0:
  print(n)
elif min_pre < -2:
  print(0)
else:
  pos = -1
  for i in range(1,n+1):
    if pre_sum[i] < 0:
      pos = i
      break
  cnt = 0
  for i in range(pos):# 之前的输都可以举手
    if a[i] == -1:
      cnt += 1
  print(cnt)

https://leetcode.cn/problems/count-submatrices-with-top-left-element-and-sum-less-than-k

python 复制代码
class Solution:
    def countSubmatrices(self, grid: List[List[int]], k: int) -> int:
        ans = 0
        n,m = len(grid),len(grid[0])
        s = [[0]*(m+1) for _ in range(n+1)]
        for i,row in enumerate(grid):# 二维前缀和
            for j,x in enumerate(row):
                # if i == 0 and j == 0:
                #     s[i][j] = x
                # elif i == 0:
                #     s[i][j] = s[i][j-1] + x
                # elif j == 0:
                #     s[i][j] = s[i-1][j] + x
                # else:
                #     s[i][j] = s[i][j-1] + s[i-1][j] - s[i-1][j-1] + x
                # if s[i][j] <= k:
                #     ans += 1
                s[i+1][j+1] = s[i+1][j] + s[i][j+1] - s[i][j] + x
                if s[i+1][j+1] <= k:
                    ans += 1
        return ans

差分:

https://leetcode.cn/problems/corporate-flight-bookings

python 复制代码
class Solution:
    def corpFlightBookings(self, bookings: List[List[int]], n: int) -> List[int]:
        diff = [0] * (n+2)
        for first,last,seats in bookings:
            diff[first] += seats
            diff[last + 1] -= seats
        res = []
        current = 0
        for i in range(1,n+1):
            current += diff[i]
            res.append(current)
        return res

https://leetcode.cn/problems/increment-submatrices-by-one

python 复制代码
class Solution:
    def rangeAddQueries(self, n: int, queries: List[List[int]]) -> List[List[int]]:
        # 二维差分
        diff = [[0]*(n+2) for _ in range(n + 2)]
        for r1,c1,r2,c2 in queries:
            diff[r1+1][c1+1] += 1
            diff[r1+1][c2+2] -= 1
            diff[r2+2][c1+1] -= 1
            diff[r2+2][c2+2] += 1
        ans = [[0]*n for  _ in range(n)]
        for i in range(n):
            for j in range(n):
                diff[i+1][j+1] = diff[i+1][j] + diff[i][j+1] - diff[i][j] + diff[i+1][j+1]
                ans[i][j] = diff[i+1][j+1]
        return ans

滑动窗口:

https://ac.nowcoder.com/acm/problem/269221

python 复制代码
n,k = map(int,input().split())
x = list(map(int,input().split()))
x.sort()
left = 0
max_cnt = 0
for right in range(n):
  while x[right] - x[left] > k:# 维护窗口
    left += 1
  max_cnt = max(max_cnt,right - left + 1)
print("%.20f" % (max_cnt / n))

递推:

https://ac.nowcoder.com/acm/problem/14975

python 复制代码
f=[0]*81
f[1]=1
f[2]=2
for i in range(3,81):
    f[i]=f[i-1]+f[i-2]# 最后一块放1*1 或最后一块放1*2
t=int(input())
for _ in range(t):
    n=int(input())
    print(f[n])

递归:

https://leetcode.cn/problems/find-the-punishment-number-of-an-integer

python 复制代码
class Solution:
    def punishmentNumber(self, n: int) -> int:
        def check(t,x):
            if t == x:
                return True
            d = 10
            while t>=d and t%d<=x:
                if check(t//d,x-(t%d)):# 前面剩下的部分,剩下需要凑的和
                    return True
                d *= 10
            return False
        return sum([i*i if check(i*i,i) else 0 for i in range(1,n+1)])

分治:

https://leetcode.cn/problems/longest-substring-with-at-least-k-repeating-characters

python 复制代码
class Solution:
    def longestSubstring(self, s: str, k: int) -> int:
        if len(s) < 0:
            return 0
        for c in set(s):
            if s.count(c) < k:# 以c为分隔符拆分字符串
                return max(self.longestSubstring(t,k) for t in s.split(c))
        return len(s)

https://leetcode.cn/problems/longest-nice-substring

python 复制代码
class Solution:
    def longestNiceSubstring(self, s: str) -> str:
        if len(s)<2:
            return ""
        for i,c in enumerate(s):
            # if c.upper() not in s or c.lower() not in s:
            if c.swapcase() not in s:
                return max(self.longestNiceSubstring(s[:i]),self.longestNiceSubstring(s[i+1:]),key = len)# 答案在左边或右边部分
        return s

贪心:

https://www.luogu.com.cn/problem/P8597

python 复制代码
s1 = input()
s2 = input()
if s1 == s2:
    print(0)
else:
    cnt = 0
    for i in range(len(s1)-1):# 从前往后比较
        if s1[i] != s2[i]:
            s1_l = list(s1)
            s1_l[i] = '*' if s1_l[i] == 'o' else 'o'
            s1_l[i+1] = '*' if s1_l[i+1] == 'o' else 'o'
            s1 = ''.join(s1_l)
            cnt += 1
    print(cnt)

https://ac.nowcoder.com/acm/problem/288123

python 复制代码
n = int(input())
ma = n//2
mi = (n+1)//3# 隔一个染色,n/3向上取整
print(mi,ma)

https://ac.nowcoder.com/acm/problem/276108

python 复制代码
a,b,x = map(int,input().split())
n = x // 3# 能买多少份3只装
m = x % 3# 买完n份3只装后,还需要补几只
if a*3 < b:# 3只单买比3只装还便宜
  print(a * x)
elif a*2 < b:#2只单买的钱 < 1份3只装的钱(补2只时买单只更划算)
  print(n * b + a * m)
elif a < b:#1只单买的钱 < 1份3只装的钱(补1只时买单只,补2只时买1份3只装更划算)
  if m == 0:
    print(n * b)
  elif m == 2:
    print((n + 1) * b)
  else:
    print(n * b + a)
else:#单买比3只装还贵 → 剩下的不管补1/2只,都直接多买1份3只装
  if m == 0:
    print(n * b)
  else:
    print((n + 1) * b)

https://ac.nowcoder.com/acm/problem/271809

python 复制代码
n,k = map(int,input().split())
a = list(map(int,input().split()))
a.sort()  
total=sum(a)
if total%k==0:
    print(0)
elif total<k:
    print(n)
else:
    res=total%k 
    cnt=0
    i=-1 #从后往前遍历(从数量最大的颜色开始)
    while cnt<=res:
        cnt+=a[i]
        i-=1
    print(-1-i)

https://ac.nowcoder.com/acm/problem/261665

python 复制代码
n,k=map(int,input().split())
l=k//2# 横切次数和竖切次数尽可能接近
ans=n**2/(l+1)/(k-l+1)
print(f"{ans:.2f}")

https://ac.nowcoder.com/acm/problem/267923

python 复制代码
for _ in range(int(input())):
  n = int(input())
  a = list(map(int,input().split()))
  a.sort()
  diff = 0# 记录前面所有负数对当前元素的总影响
  sum = [0 for i in range(n+1)]# sum[i]表示第i个元素处理完后,需要传递给后续元素的增量
  for i in range(n):
    diff += sum[i]
    a[i] += diff
    if a[i] < 0:# 如果当前元素是负数:传递给后面所有元素
      sum[i+1] += a[i]
    elif i + 1 < n: # 如果当前元素非负:只传递给下一个元素
      a[i+1] += a[i]
  print(a[-1])

https://ac.nowcoder.com/acm/problem/281749

python 复制代码
n,x = map(int,input().split())
a = list(map(int,input().split()))# 最大值
b = a.copy()# 最小值
sp = -999
if a[0] == sp:
  a[0] = 50
  b[0] = -50
c1,c2 = 0,0
for i in range(1,n):
  if a[i] == sp:
    a[i] = (50 if a[i-1]-x < -50 else a[i-1]-x)
    b[i] = max(-50,b[i-1]-(x-1))
  if a[i-1] - a[i] >= x:
    c1 += 1
  if b[i-1] - b[i] >= x:
    c2 += 1
print(c1,c2)

图论:

Floyd:

https://leetcode.cn/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance

python 复制代码
class Solution:
    def findTheCity(self, n: int, edges: List[List[int]], distanceThreshold: int) -> int:
        res,idx = inf,0
        grid = [[inf] * n for _ in range(n)]
        for u,v,w in edges:
            grid[u][v] = grid[v][u] = w
        for k in range(n):
            for u in range(n):
                for v in range(n):
                    grid[u][v] = min(grid[u][v],grid[u][k]+grid[k][v])
        for u in range(n):
            cnt = sum(u != v and grid[u][v] <= distanceThreshold for v in range(n))
            if cnt <= res:
                res,idx = cnt,u
        return idx

Dijkstra:

https://leetcode.cn/problems/network-delay-time

python 复制代码
class Solution:
    def networkDelayTime(self, times: List[List[int]], n: int, k: int) -> int:
        grid = [[inf] * (n+1) for _ in range(n+1)]
        m = len(times)
        for i in range(m):
            u,v,w = times[i]
            grid[u][v] = w
        d = [inf] * (n+1)# 最短路径列表
        d[k] = 0# 起点到自身的距离为0
        s = set()# 已经确定的节点集合
        for _ in range(n-1):
            x = -1# 初始化待选节点为-1(无节点)
            for u in range(1,n+1):# 从未确定节点中找距离起点最近的节点x
                if u not in s and(x < 0 or d[u] < d[x]):
                    x = u
            s.add(x)# 将x加入已确定集合,后续不再修改x的最短路径
            for u in range(1,n+1):# 松弛操作:以x为中间节点,更新所有节点的最短路径
                d[u] = min(d[u],d[x]+grid[x][u])
        res = max(d[1:])
        return res if res < inf else -1

数论:

GCD:

https://ac.nowcoder.com/acm/problem/16710

python 复制代码
import math
a, b = map(int, input().split())
print(a // math.gcd(a, b) * b)# LCM(a, b) = (a × b) / GCD(a, b)

https://ac.nowcoder.com/acm/problem/275615

python 复制代码
import math
a = input()
b = int(input())
# gcd(a,b)=gcd(b,a mod b)
# 计算超大数 a 对 b 的模,逐位计算
c = 0
# mod=(mod×10+int(c))%b
for i in a:
  c *= 10
  c += int(i)
  c %= b
print(math.gcd(b,c))

快速幂:

https://ac.nowcoder.com/acm/problem/23046

python 复制代码
def ksm(A, B, P):# 底数 指数 模数
    result = 1
    while B:
        if B % 2 == 1:
            result = (result * A) % P
        A = (A * A) % P
        B = B // 2
    return result
  
n = int(input())
while n:
    n -= 1
    a,b,p = map(int,input().split())
    print(ksm(a,b,p))

质数:

https://ac.nowcoder.com/acm/problem/266427

python 复制代码
n = int(input())
if n < 2:
  print(0)
else:
  is_prime = [True] * (n + 1)
  is_prime[0] = is_prime[1] = False
  # 埃氏筛
  for i in range(2,int(n**0.5) + 1):# 遍历2到√n
    if is_prime[i]:
      for j in range(i*i,n + 1,i):
        is_prime[j] = False
  primes = [i for i,prime in enumerate(is_prime) if prime]
  count = 0# 奇数
  for i in primes:
    current = i
    while current <= n:
      count += 1
      current *= i
  print(n - count - 1)

博弈:

https://ac.nowcoder.com/acm/problem/201610

python 复制代码
def func(n):
  if n == 1:
    return 0
  count = 0# 质因数总指数
  # 分解出所有因数2
  while n % 2 == 0:
    count += 1
    n //= 2
  i = 3
  # 分解出所有奇质数
  while i * i <= n:# 只需遍历到√n
    while n % i == 0:
      count += 1
      n //= i
    i += 2
  if n > 2:# # 剩下一个质数
    count += 1
  return count

n = int(input())
s = func(n) - 1
if s <= 0:
    print("Nancy")
else:
    if s % 2 == 1:
        print("Johnson")
    else:
        print("Nancy")

数据结构:

链表:

https://ac.nowcoder.com/acm/problem/233662

python 复制代码
n = int(input())
a = []
for _ in range(n):
  s = input()
  if s[:6] == 'insert':
    x = int(s.split()[1])
    y = int(s.split()[2])
    if x in a:
      a.insert(a.index(x),y)
    else:
      a.append(y)
  elif s[:6] == 'delete':
    if int(s.split()[1]) in a:
      a.remove(int(s.split()[1]))
if len(a) > 0:
  for i in a:
    print(i,end = ' ')
else:
  print("NULL")

优先队列:

https://ac.nowcoder.com/acm/problem/50439

python 复制代码
import queue
n = int(input())
a = []
for _ in range(n):
  v,s = map(int,input().split())
  a.append([v,s])
ans = sums = 0
a.sort(key=lambda x : x[1],reverse=True)# 先处理允许团人数更多的士兵
q = queue.PriorityQueue()# 小根堆:用来维护当前选中的最小战力
for i in range(n):
  v = a[i][0]
  sums += v
  q.put(v)
  while q.qsize() > a[i][1]: # 如果当前选中人数 > s[i],就踢出战力最小的士兵
    sums -= q.get()
  ans = max(ans,sums)
print(ans)

最小堆:

https://ac.nowcoder.com/acm/problem/214362

python 复制代码
import heapq
import sys

input = sys.stdin.readline
n,m,k = map(int,input().split())
arr = list(map(int,input().split()))
# 取负数,用最小堆模拟最大堆,维护前k大元素
arr = list(map(lambda x:-x,arr))
heapq.heapify(arr)

for _ in range(m):
    # 始终维护堆大小不超过k,保留当前最大的k个元素
    while len(arr) > k:
        heapq.heappop(arr)
    p = list(map(int,input().split()))
    if p[0] == 1:
        # 添加新元素(取负后入堆)
        heapq.heappush(arr,-p[1])
    else:
        # 查询前k大元素中的最小值(堆顶取负还原)
        if len(arr) < k:
            print(-1)
        else:
            print(-arr[0])

大根堆:

https://ac.nowcoder.com/acm/problem/233691

python 复制代码
import heapq
n = int(input())
heap = []
for _ in range(n):
  op = input()
  if op.split()[0] == 'push':
    x = int(op.split()[1])
    heapq.heappush(heap,-x)
  elif op.split()[0] == 'top':
    if not heap:
      print("empty")
    else:
      print(-heap[0])
  elif op.split()[0] == 'pop':
    if not heap:
      print("empty")
    else:
      print(-heapq.heappop(heap))

搜索:

BFS:

https://leetcode.cn/problems/max-area-of-island

python 复制代码
class Solution:
    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        n,m = len(grid),len(grid[0])
        res = 0
        di = [(1,0),(-1,0),(0,-1),(0,1)]  # 上下左右四个方向偏移量
        def bfs(i,j):
            ans = 1
            q = deque([(i,j)])
            grid[i][j] = 0  # 标记为已访问,避免重复计算
            while q:
                x,y = q.popleft()
                for dx,dy in di:
                    nx,ny = x + dx,y + dy
                    # 边界检查 + 陆地判断
                    if 0<=nx<n and 0<=ny<m and grid[nx][ny]:
                        q.append((nx,ny))
                        ans += 1  # 累加岛屿面积
                        grid[nx][ny] = 0  # 标记已访问
            return ans
        for i,row in enumerate(grid):
            for j,x in enumerate(row):
                if x == 1:  # 发现未访问的陆地,启动BFS
                    res = max(res,bfs(i,j))  # 更新最大岛屿面积
        return res

https://www.lanqiao.cn/problems/149/learning/

python 复制代码
from collections import deque
n,m = map(int,input().split())
di = [(1,0),(-1,0),(0,-1),(0,1)]
g = [[0] * m for _ in range(n)]
q = deque()
for i in range(n):
  r = input()
  for j,x in enumerate(r):
    if x == 'g':
      g[i][j] = 1
      q.append((i,j))
k = int(input())
while q and k:
  for _ in range(len(q)):
    x,y = q.popleft()
    for dx,dy in di:
      nx,ny= x + dx,y + dy
      if 0<=nx<n and 0<=ny<m and g[nx][ny] == 0:
        g[nx][ny] = 1
        q.append((nx,ny))
  k -= 1
for row in g:
  print(''.join('g' if x == 1 else '.' for x in row))

DFS:

https://leetcode.cn/problems/permutations

python 复制代码
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        result = []
        def dfs(start):
            if start == n:
                result.append(nums.copy())
                return
            for i in range(start,n):
                nums[start],nums[i] = nums[i],nums[start]
                dfs(start+1)
                nums[start],nums[i] = nums[i],nums[start]
        dfs(0)
        # t = itertools.permutations(nums)
        # result = [list(i) for i in t] 
        return result

https://leetcode.cn/problems/permutations-ii

python 复制代码
class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        nums.sort()
        result = []
        def dfs(start):
            if start == n:
                result.append(nums.copy())
                return
            used = set()
            for i in range(start,n):
                if nums[i] in used:
                    continue
                used.add(nums[i])
                nums[start],nums[i] = nums[i],nums[start]
                dfs(start+1)
                nums[start],nums[i] = nums[i],nums[start]
        dfs(0)
        # t1 = itertools.permutations(nums)
        # t2 = set(t1)
        # result = [list(i) for i in t2] 
        return result

https://leetcode.cn/problems/number-of-squareful-arrays

python 复制代码
class Solution:
    def numSquarefulPerms(self, nums: List[int]) -> int:
        n = len(nums)
        nums.sort()
        cnt = 0
        def pd(num):
            sqrt_n = int(num**0.5)
            return sqrt_n * sqrt_n == num
        def dfs(start):
            nonlocal cnt
            if start == n:
                cnt += 1
            used = set()
            for i in range(start,n):
                if nums[i] in used:
                    continue
                if start > 0 and not pd(nums[start-1] + nums[i]):
                    continue
                used.add(nums[i])    
                nums[start],nums[i] = nums[i],nums[start]
                dfs(start+1)
                nums[start],nums[i] = nums[i],nums[start]
        dfs(0)
        return cnt

https://leetcode.cn/problems/subsets

python 复制代码
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        n = len(nums)
        res,cur = [],[]
        def dfs(i):
            if i == n:
                res.append(cur.copy())
                return 
            cur.append(nums[i])
            dfs(i+1)
            cur.pop()
            dfs(i+1)
        # def dfs(i):
        #     res.append(cur.copy())
        #     for j in range(i,n):
        #         cur.append(nums[j])
        #         dfs(j+1)
        #         cur.pop()
        dfs(0)
        return res

https://leetcode.cn/problems/combination-sum

python 复制代码
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        n,res,cur = len(candidates),[],[]
        def dfs(i,curSum):
            if curSum == target:
                res.append(cur.copy())
                return
            if curSum > target:
                return
            for j in range(i,n):
                x = candidates[j]
                if curSum + x <= target:
                    cur.append(x)
                    dfs(j,curSum+x)
                    cur.pop()
                else:
                    break
        dfs(0,0)
        return res

https://leetcode.cn/problems/generate-parentheses

python 复制代码
class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        n,res,cur = len(candidates),[],[]
        def dfs(i,curSum):
            if curSum == target:
                res.append(cur.copy())
                return
            if curSum > target:
                return
            for j in range(i,n):
                x = candidates[j]
                if curSum + x <= target:
                    cur.append(x)
                    dfs(j,curSum+x)
                    cur.pop()
                else:
                    break
        dfs(0,0)
        return res

https://ac.nowcoder.com/acm/problem/262526

python 复制代码
def dfs(current,last):
  global cnt
  if len(current) == n:
    cnt += 1
    return
  for i in range(1,n+1):
    if not used[i]:
      if last is not None and is_prime[i+last]:
        continue
      used[i] = True
      dfs(current + [i],i)
      used[i] = False

n = int(input())
max_sum = 2 * n - 1
is_prime = [True] * (max_sum + 1)
is_prime[0] = is_prime[1] = False
for i in range(2,int(max_sum ** 0.5) + 1):
  if is_prime[i]:
    for j in range(i*i,max_sum + 1,i):
      is_prime[j] = False
cnt = 0
used = [False] * (n + 1)
dfs([],None)
print(cnt)

https://www.lanqiao.cn/problems/2193/learning/

python 复制代码
N,A,B = map(int,input().split())
SN = str(N)
res = 0
def dfs(i,n,a,b):
  global res
  if i >= len(SN):
    res = max(res,n)
    return
  x = int(SN[i])
  d = min(9-x,a)
  dfs(i+1,n*10+x+d,a-d,b)
  if b >= x+1:
    dfs(i+1,n*10+9,a,b-(x+1))
dfs(0,0,A,B)
print(res)

https://www.lanqiao.cn/problems/182/learning/

python 复制代码
sys.setrecursionlimit(10000)
N = int(input())
g = [0] + list(map(int,input().split()))
res = 0
d = {}
def dfs(u,idx):
  global res
  if d.get(u) is not None:
    res = max(res,idx-d[u])
    return
  d[u] = idx
  dfs(g[u],idx+1)
for u in range(1,N+1):
  dfs(u,1)
print(res)  

https://leetcode.cn/problems/minimum-moves-to-spread-stones-over-grid

python 复制代码
class Solution:
    def minimumMoves(self, grid: List[List[int]]) -> int:
        from_,to = [],[]
        for i,row in enumerate(grid):
            for j,num in enumerate(row):
                if num > 1:
                    from_.extend([(i,j)]*(num-1))
                elif num == 0:
                    to.append((i,j))
        ans = inf
        for from2 in permutations(from_):
            total = 0
            for (x1,y1),(x2,y2) in zip(from2,to):
                total += abs(x1-x2) + abs(y1-y2)
            ans = min(ans,total)
        return ans

https://leetcode.cn/problems/n-queens

python 复制代码
class Solution:
    def solveNQueens(self, n: int) -> List[List[str]]:
        result = []
        board = [['.' for _ in range(n)] for _ in range(n)]
        # def check(row,col):
        #     for i in range(row):
        #         if board[i][col] == 'Q':
        #             return False
        #     i,j = row-1,col-1
        #     while i>=0 and j>=0:
        #         if board[i][j] == 'Q':
        #             return False
        #         i -= 1
        #         j -= 1
        #     i,j = row-1,col+1
        #     while i>=0 and j<n:
        #         if board[i][j] == 'Q':
        #             return False
        #         i -= 1
        #         j += 1
        #     return True
        # def dfs(row):
        #     if row == n:
        #         temp = [''.join(line) for line in board]
        #         result.append(temp)
        #         return
        #     for col in range(n):
        #         if not check(row,col):
        #             continue
        #         board[row][col] = 'Q'
        #         dfs(row+1)
        #         board[row][col] = '.'
        cols = set()
        diag1 = set()
        diag2 = set()
        def dfs(row):
            if row == n:
                temp = [''.join(line) for line in board]
                result.append(temp)
                return
            for col in range(n):
                if col in cols or (row - col) in diag1 or (row + col) in diag2:
                    continue
                board[row][col] = "Q"
                cols.add(col)
                diag1.add(row - col)
                diag2.add(row + col)
                dfs(row + 1)
                board[row][col] = "."
                cols.remove(col)
                diag1.remove(row - col)
                diag2.remove(row + col)
        dfs(0)
        return result

https://leetcode.cn/problems/M99OJA

python 复制代码
class Solution:
    def partition(self, s: str) -> List[List[str]]:
        n,result,cur = len(s),[],[]
        def dfs(i):
            if i == n:
                result.append(cur.copy())
                return
            for j in range(i+1,n+1):
                temp = s[i:j]
                if temp == temp[::-1]:
                    cur.append(temp)
                    dfs(j)
                    cur.pop()
        dfs(0)
        return result

https://leetcode.cn/problems/restore-ip-addresses

python 复制代码
class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        n,result,cur = len(s),[],[]
        def dfs(i):
            if len(cur) == 4:
                if i == n:
                    result.append('.'.join(cur))
                return
            for j in range(i+1,n+1):
                temp = s[i:j]
                if temp == '0' or '0' not in temp[0] and int(temp) <= 255:
                    cur.append(temp)
                    dfs(j)
                    cur.pop()
        dfs(0)
        return result

https://www.luogu.com.cn/problem/P15435

python 复制代码
from itertools import permutations
from math import gcd
import sys
input = sys.stdin.readline
n = int(input())
nums = list(range(1,9))
max_gcd = 0
res = float('inf')
def dfs(p,q):
    global max_gcd,res
    if len(p) == 9:
        t = int(''.join(map(str,p)))
        cur_gcd = gcd(n,t)
        if max_gcd < cur_gcd:
            max_gcd = cur_gcd
            res = t
        elif max_gcd == cur_gcd:
            if t < res:
                res = t
        return
    if q > 8:
        return
    for i in range(1,9):
        p.insert(q,i)
        dfs(p,q+1)
        p.pop(q)    
    dfs(p,q+1)
perms = permutations(nums,8)
for p in perms:
    p = list(p)
    dfs(p,0)
print(res)

https://www.luogu.com.cn/problem/P6183

python 复制代码
import sys
sys.setrecursionlimit(1000000)
n = int(input())
v = set()
def out(s):
    print(s)
def dfs(cur):
    if cur in v:
        return False
    v.add(cur)
    out(cur)
    for i in range(n):
        s_l = list(cur)
        s_l[i] = 'X' if s_l[i] == 'O' else 'O'
        n_s = ''.join(s_l)
        if dfs(n_s):
            return True
    return True
start = 'O'*n
dfs(start)
print(start,end="")

https://www.luogu.com.cn/problem/P13886

python 复制代码
import sys
sys.setrecursionlimit(1000000)
cnt = 0
A = 9
B = 16
def dfs(n,a,b):
    global cnt
    if n == 7:
        if a == 0 and b == 0:
            cnt += 1
        return
    for i in range(a+1):
        for j in range(b+1):
            if 2 <= i+j <= 5:
                dfs(n+1,a-i,b-j)
dfs(0,A,B)
print(cnt)

https://www.luogu.com.cn/problem/P2386

python 复制代码
# cnt,s,cur = 0,set(),[]
# def dfs(m,n):
#     global cnt,s,cur
#     if n == 0:
#         if m == 0:
#             c_s = tuple(sorted(cur))
#             if c_s not in s:
#                 s.add(c_s)
#                 cnt += 1
#         return
#     if m < 0:
#         return
#     for i in range(m+1):
#         cur.append(i)
#         dfs(m-i,n-1)
#         cur.pop()
# for _ in range(int(input())):
#     M,N = map(int,input().split())
#     cnt = 0
#     s.clear()
#     cur.clear()
#     dfs(M,N)
#     print(cnt)
def dfs(m,n,cur,start):
    global res
    if n == 0:
        if m == 0:
            res.append(cur.copy())
        return
    if m < start * n:# 剪枝
        return
    for i in range(start, m+1):# 从start开始,非递减去重
        cur.append(i)
        dfs(m-i,n-1,cur,i)
        cur.pop()
for _ in range(int(input())):
    M,N = map(int,input().split())
    res = []
    dfs(M,N,[],0)
    print(len(res))

动态规划:

https://leetcode.cn/problems/climbing-stairs

python 复制代码
class Solution:
    def climbStairs(self, n: int) -> int:
        def dfs(n):
            return 1 if n == 1 or n == 0 else dfs(n-1)+dfs(n-2)
        return dfs(n)

https://leetcode.cn/problems/house-robber

python 复制代码
class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        f = [[0]*2 for _ in range(n + 1)]
        for i in range(1,n+1):
            f[i][0] = max(f[i-1][0],f[i-1][1])
            f[i][1] = f[i-1][0] + nums[i-1]
        return max(f[n][0],f[n][1])

https://leetcode.cn/problems/longest-increasing-subsequence

python 复制代码
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        f = [1]*len(nums)
        for i,x in enumerate(nums):
            for j in range(i):
                if nums[j] < nums[i]:
                    f[i] = max(f[i],f[j]+1)
        return max(f)

https://www.luogu.com.cn/problem/P1048

python 复制代码
T,M = map(int,input().split())
t,m = [0]*(M+1),[0]*(M+1)
for i in range(1,M+1):
    t[i],m[i] = map(int,input().split())
dp = [[0] * (T+1) for _ in range(M+1)]
for i in range(1,M+1):
    for j in range(1,T+1):
        if j - t[i] >= 0:
            dp[i][j] = max(dp[i-1][j],dp[i-1][j-t[i]] + m[i])
        else:
            dp[i][j] = dp[i-1][j]
print(dp[M][T])
相关推荐
云泽8082 小时前
蓝桥杯算法精讲:从宏观角度重新认识递归
算法·职场和发展·蓝桥杯
云姜.2 小时前
LLM接入方式
python
自信150413057592 小时前
插入排序算法
c语言·数据结构·算法·排序算法
阳光永恒7362 小时前
Python零基础入门全套资料包免费分享 | 从0到1系统学习路线(含课件+源码+实战案例)
开发语言·python·学习·编程入门·python教程·编程学习·免费资料
紫丁香2 小时前
pytest_自动化测试1
开发语言·python·功能测试·单元测试·pytest
酷酷的橙子2 小时前
python 学习
python
阿Y加油吧2 小时前
力扣打卡day09——缺失的第一个正数、矩阵置零
数据结构·算法·leetcode
2301_818419012 小时前
C++中的状态模式实战
开发语言·c++·算法
仰泳的熊猫2 小时前
题目2576:蓝桥杯2020年第十一届省赛真题-解码
数据结构·c++·算法·蓝桥杯