(题目持续更新,建议收藏)
语法基础:
日期问题:
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:

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])