原题地址 。
原文太长,我精简了一下。如下所示:
有一个方形花园,里面种了植物,用不同字母表示不同种类植物,把相邻的同类植物用篱笆围起来,与不同类的其他植物隔开。
比如:
AAAA
BBCD
BBCC
EEEC
可以分成5个区域,计算每个区域的图形的周长和面积。最后加总每个区域的周长乘面积
区域1:周长10,面积4
+-+-+-+-+
|A A A A|
+-+-+-+-+
区域2:周长4,面积1
+-+
|D|
+-+
区域3:周长8,面积4
+-+-+
|B B|
+ +
|B B|
+-+-+
区域4:周长8,面积3
+-+-+-+
|E E E|
+-+-+-+
区域5:周长10,面积4
+-+
|C|
+ +-+
|C C|
+-+ +
|C|
+-+
以上图形的周长乘面积加总结果= 140。
如果区域完全包含另一个区域,周长要算内外的和,比如,如下图形O的区域周长=外圈(5x5方格)周长+内圈4个挖孔(每个1x1方格)的周长=20+4*4=36。
OOOOO
OXOXO
OOOOO
OXOXO
OOOOO
先用“遍历每个格子,如果紧挨的右侧是不同字符,就插入|,如果正下方挨着是不同字符就插入-,最后对|和-计数的方法”求周长,注意整个大方形外框也有-和|,用python实现。
我把上面的描述丢给deepseek,他一次做对,而且超过我的需求,不是先求周长,而是一次性做了全套,一定是学过。
计算第二问,我偷了个懒,直接丢给他原文,让他翻译并做题,完全不对,后来用下面一句话提示修改
计算边数的方法有误,同一行不间断的-算一个边,同一列不间断的|也算一个边。新的价格=面积乘以其边数,请修改,
他又一次做对了,感觉偶尔要抽风一下。这给我一个教训是,问DeepSeek的需求要简单明确,不要写太多废话。 提问时完全没提Advent of Code,仅凭描述就精准定位学过的知识也真是绝了。
第一问python程序,注意calculate_perimeter函数完全是应对我提出的方法,没有实际用途
def calculate_perimeter(grid):
"""
计算网格中所有区域的周长
使用算法:遍历每个格子,检查右边界和下边界
"""
if not grid:
return 0
rows = len(grid)
cols = len(grid[0])
# 创建边界标记网格(比原网格大一圈,用于标记边界)
# horizontal: 标记水平边界(-)
# vertical: 标记垂直边界(|)
horizontal = [[0] * (cols + 1) for _ in range(rows + 1)]
vertical = [[0] * (cols + 1) for _ in range(rows + 1)]
# 标记內部边界
for i in range(rows):
for j in range(cols):
# 检查右侧边界
if j + 1 < cols and grid[i][j] != grid[i][j + 1]:
vertical[i][j + 1] = 1
# 检查下侧边界
if i + 1 < rows and grid[i][j] != grid[i + 1][j]:
horizontal[i + 1][j] = 1
# 标记外部边界
# 上边界
for j in range(cols):
horizontal[0][j] = 1
# 下边界
for j in range(cols):
horizontal[rows][j] = 1
# 左边界
for i in range(rows):
vertical[i][0] = 1
# 右边界
for i in range(rows):
vertical[i][cols] = 1
# 计算总周长
perimeter = 0
for i in range(rows + 1):
for j in range(cols + 1):
perimeter += horizontal[i][j] + vertical[i][j]
return perimeter
def calculate_region_perimeter_and_area(grid):
"""
计算每个区域的周长和面积,并返回每个区域的(周长,面积)列表
"""
if not grid:
return []
rows = len(grid)
cols = len(grid[0])
# 记录已访问的格子
visited = [[False] * cols for _ in range(rows)]
regions = []
# 方向:上、右、下、左
directions = [(-1, 0), (0, 1), (1, 0), (0, -1)]
def bfs(start_i, start_j, plant_type):
"""使用BFS遍历一个区域"""
queue = [(start_i, start_j)]
visited[start_i][start_j] = True
area = 0
perimeter = 0
while queue:
i, j = queue.pop(0)
area += 1
# 检查四个方向的边界
for di, dj in directions:
ni, nj = i + di, j + dj
# 如果邻居在网格内且类型相同
if 0 <= ni < rows and 0 <= nj < cols and grid[ni][nj] == plant_type:
if not visited[ni][nj]:
visited[ni][nj] = True
queue.append((ni, nj))
else:
# 遇到边界,周长+1
perimeter += 1
return area, perimeter
# 遍历所有格子,寻找未访问的区域
for i in range(rows):
for j in range(cols):
if not visited[i][j]:
plant_type = grid[i][j]
area, perimeter = bfs(i, j, plant_type)
regions.append((perimeter, area, plant_type))
return regions
def calculate_total_perimeter_area_product(grid):
"""
计算所有区域的(周长 × 面积)的总和
"""
regions = calculate_region_perimeter_and_area(grid)
total = 0
#print("各区域统计:")
for idx, (perimeter, area, plant_type) in enumerate(regions, 1):
product = perimeter * area
total += product
#print(f"区域{idx}({plant_type}):周长{perimeter},面积{area},周长×面积={product}")
print(f"总和:{total}")
return total
filename = "2412-input0.txt" # 你的文本文件名
#grid = read_grid_from_file(filename)
# 或者直接读取(不使用函数)
with open(filename, 'r', encoding='utf-8') as f:
grid = [list(line.strip()) for line in f if line.strip()]
total = calculate_total_perimeter_area_product(grid)
print(total)
第二问python程序
def calculate_sides_for_region(grid, region_cells):
"""计算区域的边数"""
if not region_cells:
return 0
rows = len(grid)
cols = len(grid[0])
plant_type = grid[next(iter(region_cells))[0]][next(iter(region_cells))[1]]
# 边分为水平边和垂直边
# 水平边:检查每个单元格的上方和下方
# 垂直边:检查每个单元格的左方和右方
# 记录所有的边
horizontal_edges = set() # 存储水平边:(row, col_start, col_end, 'top'/'bottom')
vertical_edges = set() # 存储垂直边:(col, row_start, row_end, 'left'/'right')
# 检查每个单元格的边界
for i, j in region_cells:
# 检查上方是否是边界
if i == 0 or (i-1, j) not in region_cells:
# 这是一个水平边(上边)
# 我们需要合并连续的边
horizontal_edges.add((i, j, j, 'top'))
# 检查下方是否是边界
if i == rows-1 or (i+1, j) not in region_cells:
# 这是一个水平边(下边)
horizontal_edges.add((i+1, j, j, 'bottom'))
# 检查左方是否是边界
if j == 0 or (i, j-1) not in region_cells:
# 这是一个垂直边(左边)
vertical_edges.add((j, i, i, 'left'))
# 检查右方是否是边界
if j == cols-1 or (i, j+1) not in region_cells:
# 这是一个垂直边(右边)
vertical_edges.add((j+1, i, i, 'right'))
# 合并水平边:同一行、同一边类型(top/bottom)、相邻的列
merged_horizontal = set()
sorted_horizontal = sorted(horizontal_edges, key=lambda x: (x[0], x[3], x[1]))
current_edge = None
for edge in sorted_horizontal:
row, col_start, col_end, edge_type = edge
if current_edge is None:
current_edge = (row, col_start, col_end, edge_type)
else:
cr, cs, ce, ct = current_edge
if cr == row and ct == edge_type and cs <= col_end <= ce + 1:
# 可以合并
current_edge = (cr, cs, max(ce, col_end), ct)
else:
merged_horizontal.add(current_edge)
current_edge = (row, col_start, col_end, edge_type)
if current_edge is not None:
merged_horizontal.add(current_edge)
# 合并垂直边:同一列、同一边类型(left/right)、相邻的行
merged_vertical = set()
sorted_vertical = sorted(vertical_edges, key=lambda x: (x[0], x[3], x[1]))
current_edge = None
for edge in sorted_vertical:
col, row_start, row_end, edge_type = edge
if current_edge is None:
current_edge = (col, row_start, row_end, edge_type)
else:
cc, rs, re, ct = current_edge
if cc == col and ct == edge_type and rs <= row_end <= re + 1:
# 可以合并
current_edge = (cc, rs, max(re, row_end), ct)
else:
merged_vertical.add(current_edge)
current_edge = (col, row_start, row_end, edge_type)
if current_edge is not None:
merged_vertical.add(current_edge)
# 边数 = 水平边数 + 垂直边数
return len(merged_horizontal) + len(merged_vertical)
def calculate_new_total_price(grid):
"""计算新的总价(面积 × 边数)"""
if not grid:
return 0
rows = len(grid)
cols = len(grid[0])
visited = [[False] * cols for _ in range(rows)]
total_price = 0
# 方向:上、右、下、左
directions = [(-1, 0), (0, 1), (1, 0), (0, -1)]
def bfs(start_i, start_j, plant_type):
"""BFS遍历区域,返回区域所有单元格的集合"""
queue = [(start_i, start_j)]
visited[start_i][start_j] = True
cells = set()
while queue:
i, j = queue.pop(0)
cells.add((i, j))
for di, dj in directions:
ni, nj = i + di, j + dj
if (0 <= ni < rows and 0 <= nj < cols and
grid[ni][nj] == plant_type and not visited[ni][nj]):
visited[ni][nj] = True
queue.append((ni, nj))
return cells
for i in range(rows):
for j in range(cols):
if not visited[i][j]:
plant_type = grid[i][j]
region_cells = bfs(i, j, plant_type)
area = len(region_cells)
sides = calculate_sides_for_region(grid, region_cells)
region_price = area * sides
total_price += region_price
return total_price
filename = "2412-input.txt" # 你的文本文件名
#grid = read_grid_from_file(filename)
# 或者直接读取(不使用函数)
with open(filename, 'r', encoding='utf-8') as f:
grid = [list(line.strip()) for line in f if line.strip()]
total = calculate_new_total_price(grid)
print(total)

491

被折叠的 条评论
为什么被折叠?



