在 Python 中,通常情况下 (x-1), (y-1) 这种写法是用来表示坐标或索引的偏移量,其中 (x, y) 是一个二维空间中的点或位置。
(x-1) 表示在 x 轴上向左移动一个单位;
(y-1) 表示在 y 轴上向上移动一个单位。
这种写法通常用于处理数组、列表、矩阵等数据结构的索引或坐标,特别是在二维数组或矩阵中,因为索引通常是从 0 开始的。例如,如果要访问二维数组的第 (x, y) 个元素,可以使用 (x-1), (y-1) 来表示该元素在数组中的索引位置。
请注意,这种写法假设坐标或索引是从 1 开始计数的,因此需要将其减去 1 以适应 Python 中从 0 开始计数的索引方式。
DFS–基础
例题分析
分糖果
# ans表示方案数
ans = 0
# 1 usage
def dfs(depth, n, m):
# depth:第几个小朋友
# n:第一种糖果剩余余量
# m:第二种糖果剩余余量
# 当分完所有小朋友后保证手上没有糖果
if depth == 7: # 如果已经分完所有小朋友
if n == 0 and m == 0: # 如果第一种和第二种糖果剩余余量均为0
global ans
ans += 1 # 方案数加1
return
# 枚举当前小朋友的糖果可能性
# 枚举第一种糖果
for i in range(0, 6): # 第一种糖果的数量范围为0到5
# 枚举第二种糖果
for j in range(0, 6): # 第二种糖果的数量范围为0到5
# 第depth个小朋友有i个第一种糖果,j个第二种糖果
if 2 <= i+j <= 5 and i <= n and j <= m: # 如果第一种和第二种糖果总数在2到5之间,并且数量不超过剩余余量
dfs(depth+1, n-i, m-j) # 继续递归搜索下一个小朋友
dfs(0, 9, 16) # 从第0个小朋友开始搜索,第一种糖果剩余余量为9,第二种糖果剩余余量为16
print(ans) # 输出方案数
3505 西瓜
def dfs(depth, weight, cnt):
# depth:第depth个瓜
# weight:表示当前买到的瓜的重量
# cnt:表示当前批的次数
# 剪枝.当前已经不合法,没必要继续下去
if weight > m: # 如果当前买到的瓜的重量超过了目标重量m,则剪枝
return
if weight == m: # 如果当前买到的瓜的重量等于目标重量m
global ans
ans = min(ans, cnt) # 更新答案为当前批次数cnt与答案ans的较小值
if depth == n: # 如果已经遍历完所有瓜
return
# 枚举当前瓜的三种情况
# 不买
dfs(depth+1, weight+0, cnt)
# 买
dfs(depth+1, weight+A[depth], cnt)
# 买一半
dfs(depth+1, weight+A[depth] // 2, cnt+1)
# 输入
n, m = map(int, input().split()) # 输入瓜的数量n和目标重量m
m *= 2 # 将目标重量m乘以2,因为每个瓜的重量需要*2处理
A = list(map(int, input().split())) # 输入每个瓜的重量列表A
A = [x*2 for x in A] # 将每个瓜的重量乘以2,因为每个瓜的重量需要*2处理
ans = n + 1 # 初始化答案为瓜的数量n+1
dfs(0, 0, 0) # 调用dfs函数,开始深度优先搜索
if ans == n + 1: # 如果答案仍然为初始值n+1,表示没有找到符合条件的解
ans = -1 # 将答案设为-1
print(ans) # 输出答案
DFS–回溯
回溯法
def dfs(depth):
# depth:第depth个数字
if depth == n: # 如果已经选择完所有数字
print(path) # 打印当前路径
return
# 第depth个数字可以从1-n进行选择
for i in range(1, n+1): # 遍历数字1到n
# 选择的数字必须未被标记
if vis[i]: # 如果数字i已经被选择过
continue # 跳过选择
# 第depth个数字选择i
vis[i] = True # 标记数字i已经被选择
path.append(i) # 将数字i添加到路径中
dfs(depth + 1) # 继续选择下一个数字
vis[i] = False # 恢复数字i的未选择状态
path.pop(-1) # 移除数字i,回溯到上一层
n = int(input()) # 输入数字n
vis = [False] * (n + 1) # 初始化数字标记列表
path = [] # 初始化路径列表
dfs(0) # 从第0个数字开始选择
求子集
n = int(input()) # 输入n
a = list(map(int, input().split())) # 输入a列表
path = [] # 定义路径数组
def dfs(depth):
# 当深度等于n时,打印路径并返回
if depth == n:
print(path)
return
# 选取当前深度对应的元素
path.append(a[depth])
dfs(depth + 1) # 递归下一层
path.pop(-1) # 不选取当前深度对应的元素
dfs(depth + 1) # 递归下一层
dfs(0) # 从第0层开始深度优先搜索
N 皇后
def dfs(x):
# 定义深度优先搜索函数,x 表示当前层级
if x == n + 1:
# 如果已经放置了 n 个皇后,即所有行都已经遍历完成
global ans
ans += 1 # 结果加一
return # 返回
# 遍历当前层级的每一列
for y in range(n):
# 当前坐标为 (x, y),需要满足当前列、主对角线、副对角线上没有皇后
if vis1[y] or vis2[x + y] or vis3[x - y + n]:
# 如果当前列已经有皇后,或者主副对角线上已经有皇后,跳过当前位置
continue
# 在当前位置放置皇后,标记当前列、主对角线、副对角线上有皇后
vis1[y] = vis2[x + y] = vis3[x - y + n] = True
# 递归调用下一层,即放置下一个皇后
dfs(x + 1)
# 回溯,撤销当前位置的皇后,继续尝试其他位置
vis1[y] = vis2[x + y] = vis3[x - y + n] = False
# 获取输入的皇后数量
n = int(input())
# 初始化三个标记数组,用于标记列、主对角线、副对角线是否已经有皇后
vis1 = [False] * (n + 1)
vis2 = [False] * (2 * n + 1)
vis3 = [False] * (2 * n + 1)
# 初始化结果变量
ans = 0
# 调用深度优先搜索函数,从第一行开始放置皇后
dfs(1)
# 输出结果
print(ans)
小朋友崇拜圈
# 定义深度优先搜索函数,用于找出环并计算环的长度
def dfs(x, length):
# 记录走到 x 的步长为 length
vis[x] = length
# 接下来要走下一个点
# 判断下一个点是否走过
if vis[a[x]] != 0:
# 此时存在环
global ans
ans = max(ans, length - vis[a[x]] + 1)
pass
else:
dfs(a[x], length + 1)
# 输入点的个数
n = int(input())
# 输入每个点的下一个点的索引,注意索引从1开始,所以在前面添加了一个0
a = [0] + list(map(int, input().split()))
# 标记数组: vis[x] 表示点 x 的步数
vis = [0] * (n + 1)
# 初始化结果变量
ans = 0
# 遍历每个点,对于每个单独的环,都要做一遍深度优先搜索
for i in range(1, n + 1):
if vis[i] == 0:
dfs(i, 1)
# 输出结果
print(ans)
def dfs(x, length)::定义了一个深度优先搜索函数 dfs,其中 x 表示当前遍历到的点的索引,length 表示当前路径的长度。
vis[x] = length:将当前点的步数记录为 length。
if vis[a[x]] != 0::判断当前点的下一个点是否已经被访问过。
global ans:声明 ans 为全局变量。
ans = max(ans, length - vis[a[x]] + 1):更新结果变量 ans,取当前路径长度与之前记录的路径长度的差的最大值。
else: dfs(a[x], length + 1):如果当前点的下一个点未被访问过,则继续深度优先搜索。
n = int(input()):输入点的个数。
a = [0] + list(map(int, input().split())):输入每个点的下一个点的索引,将索引保存在列表 a 中。
vis = [0] * (n + 1):初始化标记数组 vis,用于记录每个点的步数。
ans = 0:初始化结果变量 ans。
for i in range(1, n + 1)::遍历每个点。
if vis[i] == 0::如果当前点未被访问过,则进行深度优先搜索。
dfs(i, 1):调用深度优先搜索函数 dfs,从当前点开始搜索环。
print(ans):输出结果变量 ans,即找到的最长环的长度。