📅  最后修改于: 2023-12-03 14:51:34.109000             🧑  作者: Mango
在银行中,保安守卫着入口,盯着每个人进出,并确保行为正常。现在,你需要编写一段程序来帮助每个人找到与守卫的最短距离。
为了解决这个问题,我们可以使用广度优先搜索算法。我们先将保安视为起点,每个人的位置视为终点,然后搜索出最短距离。
我们需要定义以下结构:
Bank
:表示银行。包括高度和宽度两个属性 h
和 w
,以及 start
和 targets
两个点的信息。其中,start
表示保安的位置,targets
表示每个人的位置。Point
:表示地图上的一个点。包括坐标 x
和 y
,以及当前点到起点的距离 dist
。Queue
:我们使用队列来辅助实现广度优先搜索。class Bank:
def __init__(self, h: int, w: int, start: tuple, targets: List[tuple]):
self.h = h
self.w = w
self.start = start
self.targets = targets
class Point:
def __init__(self, x: int, y: int, dist: int):
self.x = x
self.y = y
self.dist = dist
class Queue:
def __init__(self):
self.queue = []
def put(self, p: Point):
self.queue.append(p)
def get(self) -> Point:
if len(self.queue) > 0:
return self.queue.pop(0)
return None
def is_empty(self) -> bool:
return len(self.queue) == 0
我们使用 BFS
来实现广度优先搜索。
为了避免重复访问同一节点,我们需要设置一个 visited
的标记来记录访问过的节点。
在计算起点与每个人的最短距离时,我们只需要计算直线距离即可。因此,在计算两个点之间的直线距离时,我们可以使用欧几里得距离公式:
$$ distance = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} $$
import math
def bfs(bank: Bank) -> int:
queue = Queue()
visited = set()
start = Point(bank.start[0], bank.start[1], 0)
queue.put(start)
visited.add((start.x, start.y))
while not queue.is_empty():
point = queue.get()
if (point.x, point.y) in bank.targets:
return point.dist
for next_point in get_next_points(point, bank):
if (next_point.x, next_point.y) not in visited:
queue.put(next_point)
visited.add((next_point.x, next_point.y))
return -1
def get_next_points(point: Point, bank: Bank) -> List[Point]:
# 上下左右四个方向
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
next_points = []
for direction in directions:
next_x, next_y = point.x + direction[0], point.y + direction[1]
if 0 <= next_x < bank.h and 0 <= next_y < bank.w:
next_point = Point(next_x, next_y, point.dist + 1)
next_points.append(next_point)
# 加入每个人的位置
for tgt in bank.targets:
distance = math.sqrt((point.x - tgt[0]) ** 2 + (point.y - tgt[1]) ** 2)
if distance < 2:
next_point = Point(tgt[0], tgt[1], point.dist + 1)
next_points.append(next_point)
return next_points
下面是一个使用示例:
if __name__ == '__main__':
bank = Bank(5, 5, (0, 0), [(1, 2), (2, 2)])
length = bfs(bank)
print(length)
这里,我们给出了一个 5x5 的银行地图,其中保安的位置是 (0, 0)
,两名顾客的位置分别是 (1, 2)
和 (2, 2)
。我们调用 bfs
函数,即可得到保安与两名顾客之间的最短距离。
# 在银行中找到与守卫的最短距离
在银行中,保安守卫着入口,盯着每个人进出,并确保行为正常。现在,你需要编写一段程序来帮助每个人找到与守卫的最短距离。
## 程序设计
为了解决这个问题,我们可以使用广度优先搜索算法。我们先将保安视为起点,每个人的位置视为终点,然后搜索出最短距离。
### 数据结构
我们需要定义以下结构:
- `Bank`:表示银行。包括高度和宽度两个属性 `h` 和 `w` ,以及 `start` 和 `targets` 两个点的信息。其中,`start` 表示保安的位置,`targets` 表示每个人的位置。
- `Point`:表示地图上的一个点。包括坐标 `x` 和 `y` ,以及当前点到起点的距离 `dist`。
- `Queue`:我们使用队列来辅助实现广度优先搜索。
```python
class Bank:
def __init__(self, h: int, w: int, start: tuple, targets: List[tuple]):
self.h = h
self.w = w
self.start = start
self.targets = targets
class Point:
def __init__(self, x: int, y: int, dist: int):
self.x = x
self.y = y
self.dist = dist
class Queue:
def __init__(self):
self.queue = []
def put(self, p: Point):
self.queue.append(p)
def get(self) -> Point:
if len(self.queue) > 0:
return self.queue.pop(0)
return None
def is_empty(self) -> bool:
return len(self.queue) == 0
我们使用 BFS
来实现广度优先搜索。
为了避免重复访问同一节点,我们需要设置一个 visited
的标记来记录访问过的节点。
在计算起点与每个人的最短距离时,我们只需要计算直线距离即可。因此,在计算两个点之间的直线距离时,我们可以使用欧几里得距离公式:
$$ distance = \sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2} $$
import math
def bfs(bank: Bank) -> int:
queue = Queue()
visited = set()
start = Point(bank.start[0], bank.start[1], 0)
queue.put(start)
visited.add((start.x, start.y))
while not queue.is_empty():
point = queue.get()
if (point.x, point.y) in bank.targets:
return point.dist
for next_point in get_next_points(point, bank):
if (next_point.x, next_point.y) not in visited:
queue.put(next_point)
visited.add((next_point.x, next_point.y))
return -1
def get_next_points(point: Point, bank: Bank) -> List[Point]:
# 上下左右四个方向
directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]
next_points = []
for direction in directions:
next_x, next_y = point.x + direction[0], point.y + direction[1]
if 0 <= next_x < bank.h and 0 <= next_y < bank.w:
next_point = Point(next_x, next_y, point.dist + 1)
next_points.append(next_point)
# 加入每个人的位置
for tgt in bank.targets:
distance = math.sqrt((point.x - tgt[0]) ** 2 + (point.y - tgt[1]) ** 2)
if distance < 2:
next_point = Point(tgt[0], tgt[1], point.dist + 1)
next_points.append(next_point)
return next_points
下面是一个使用示例:
if __name__ == '__main__':
bank = Bank(5, 5, (0, 0), [(1, 2), (2, 2)])
length = bfs(bank)
print(length)
这里,我们给出了一个 5x5 的银行地图,其中保安的位置是 (0, 0)
,两名顾客的位置分别是 (1, 2)
和 (2, 2)
。我们调用 bfs
函数,即可得到保安与两名顾客之间的最短距离。