title: 5.布线问题
date: 2023-05-02 14:54:30
categories:
- 大学课程内容
- 大二下
- 算法分析基础
5.布线问题
苏科大的sb输入输出数据,题目描述的输入输出和答案数据全是乱的。
【问题描述】
印刷电路板将布线区域划分成n*m个方格,精确的电路布线问题要求确定连接方格a的中点到方格b的中点的最短布线方案。在布线时,电路只能沿直线或直角布线。为了避免线路相交,已经布了线的方格不允许其他线穿过。对给定的电路板,找出最短的布线路径。
【输入形式】
方阵的行数、列数、布线区域方阵(其中不能通过的地方输入1,能通过的地方输入0)、起点坐标、终点坐标
【输出形式】
线路长度以及线路包含的方格坐标
【样例输入】
6 6
0 0 1 0 0 0
0 0 1 1 0 0
0 0 0 0 1 0
0 0 0 1 1 0
1 0 0 0 1 0
1 1 1 0 0 0
1 2
4 3
【样例输出】
4
1,2 > 2,2 > 3,2 > 4,2 > 4,3
【样例说明】
第1行输入方阵的行数、列数
第2-7行输入方阵元素,不能通过的地方输入1,能通过的地方输入0
第8行输入起点坐标
第9行输入终点坐标
所有元素用空格分隔, 且坐标索引从1开始!!
思路
思路很简单,就是BFS求最短路,只不过需要输出路径,那就记录前一个节点,最后回溯回去就可以
代码
import queue
# 输入地图大小
n, m = map(int, input().split())
# 初始化地图
g = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
for i in range(n):
g[i + 1] = [0]+[int(x) for x in input().split()]
# 输入起点和终点
start = tuple(map(int, input().split()))
end = tuple(map(int, input().split()))
# 初始化距离和状态数组,以及父节点数组
dist = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
st = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
father = [[(0, 0) for _ in range(m + 1)] for _ in range(n + 1)]
# BFS 队列初始化,加入起点
q = queue.Queue()
q.put(start)
st[start[0]][start[1]] = 1
flag = False
while not q.empty() and not flag:
# 弹出队首元素
t = q.get()
# 枚举四个方向
for i in range(4):
x = t[0] + [-1, 1, 0, 0][i]
y = t[1] + [0, 0, -1, 1][i]
# 判断是否越界或者障碍物已经被标记
if x < 1 or x > n or y < 1 or y > m:
continue
if g[x][y] == 0 and st[x][y] == 0:
# 如果可以走,则加入队列,更新距离,标记状态,记录父节点
q.put((x, y))
dist[x][y] = dist[t[0]][t[1]] + 1
st[x][y] = 1
father[x][y] = (t[0], t[1])
# 判断是否到达终点
if (x, y) == end:
flag = True
break
# 输出最短路距离
print(dist[end[0]][end[1]])
# 再次 BFS,打印路径
path = [end]
x = end[0]
y = end[1]
while (x, y) != start:
# 获取当前点的父节点
x, y = father[x][y]
path.append((x, y))
# 反转路径,并输出
path.reverse()
for i in range(len(path)):
if i == len(path) - 1:
print("{},{}".format(path[i][0], path[i][1]))
else:
print("{},{}".format(path[i][0], path[i][1]), end="-->")
其他三个测试数据如下:
由第一个数据看出
# 测试数据1
6 6
0 0 1 0 0 0
0 0 1 1 0 0
0 0 0 0 1 0
0 0 0 1 1 0
1 0 0 0 1 0
1 1 1 0 0 0
1 2
4 3
# 输出
4
1,2-->2,2-->3,2-->4,2-->4,3
# 测试数据2
6 6
1 1 1 1 0 0
0 0 0 0 1 0
0 0 0 1 1 0
1 0 0 0 0 0
1 1 1 0 0 0
3 1
3 6
# 输出
9
3,1-->4,1-->4,2-->5,2-->5,3-->5,4-->5,5-->5,6-->4,6-->3,6
# 测试数据3
4 4
0 1 0 0
0 1 0 1
0 0 0 0
0 0 1 1
1 1
1 4
# 输出
7
1,1-->2,1-->3,1-->3,2-->3,3-->2,3-->1,3-->1,4