布线问题求解

问题描述

此问题描述了在印刷电路板(PCB)上进行布线的需求,用网格表示 PCB。要求找到从 a 点到 b 点的最短路径,路径只能走直线或 L 形转弯(类似“日”字的路径),并且不能穿过障碍(灰色方块)。每走过一个格子,该格子就被锁定,其他路径不能通过。请添加图片描述

解决思路

  1. 定义网格:创建一个表示 PCB 的网格,标记出 ab 的位置以及障碍物(用 # 表示)。
  2. 移动约束:只能向上、下、左、右移动,并且路径只能以 L 形转弯。
  3. 广度优先搜索(BFS):使用 BFS 从 a 开始搜索到 b 的路径,确保找到的路径是最短路径。
  4. 路径验证:确保路径不穿过任何障碍或被封锁的格子。
  5. 输出:打印最短路径的步数(如果存在)。

Python代码实现

from collections import deque

# 定义方向:上、下、左、右
DIRECTIONS = [(0, 1), (1, 0), (0, -1), (-1, 0)]

def is_valid(x, y, grid):
    """检查当前位置是否在边界内且未被阻挡。"""
    return 0 <= x < len(grid) and 0 <= y < len(grid[0]) and grid[x][y] != '#'

def find_shortest_path(grid, start, end):
    m, n = len(grid), len(grid[0])
    # 使用队列进行 BFS,记录 (x, y, 方向, 步数)
    queue = deque([(start[0], start[1], -1, 0)])
    # 记录访问过的格子和方向,避免重复访问
    visited = set([(start[0], start[1], -1)])
    
    while queue:
        x, y, last_dir, steps = queue.popleft()
        
        # 如果到达终点
        if (x, y) == end:
            return steps
        
        # 遍历四个方向
        for dir_index, (dx, dy) in enumerate(DIRECTIONS):
            nx, ny = x + dx, y + dy
            
            # L 形转弯限制:允许相同方向或直角方向
            if dir_index != last_dir and last_dir != -1 and abs(dir_index - last_dir) % 2 == 0:
                continue
            
            # 检查新位置是否合法且未被访问
            if is_valid(nx, ny, grid) and (nx, ny, dir_index) not in visited:
                visited.add((nx, ny, dir_index))
                queue.append((nx, ny, dir_index, steps + 1))
    
    return -1  # 如果找不到路径,返回 -1

# 示例网格
grid = [
    ['.', '.', '.', '#', '.', '.', '.'],
    ['.', '#', '.', '.', '#', '.', '.'],
    ['.', '#', 'a', '.', '#', 'b', '.'],
    ['.', '#', '.', '.', '#', '.', '.'],
    ['.', '.', '.', '#', '.', '.', '.']
]

# 起点和终点
start = (2, 2)  # a 的位置
end = (2, 5)    # b 的位置

# 调用函数并打印结果
result = find_shortest_path(grid, start, end)
print("最短步数为:", result if result != -1 else "无可行路径")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值