最短路模型

目录


迷宫问题

题目描述:

给定一个 n × n n \times n n×n 的二维数组,如下所示:

python 复制代码
int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的 1 1 1 表示墙壁, 0 0 0 表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

数据保证至少存在一条从左上角走到右下角的路径。

输入格式:

第一行包含整数 n n n。

接下来 n n n 行,每行包含 n n n 个整数 0 0 0 或 1 1 1,表示迷宫。

输出格式:

输出从左上角到右下角的最短路线,如果答案不唯一,输出任意一条路径均可。

按顺序,每行输出一个路径中经过的单元格的坐标,左上角坐标为 ( 0 , 0 ) (0,0) (0,0),右下角坐标为 ( n − 1 , n − 1 ) (n-1,n-1) (n−1,n−1)。

数据范围:

0 ≤ n ≤ 1000 0 \le n \le 1000 0≤n≤1000

输入样例:

python 复制代码
5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出样例:

python 复制代码
0 0
1 0
2 0
2 1
2 2
2 3
2 4
3 4
4 4

代码实现

python 复制代码
import sys
from collections import deque
input = sys.stdin.readline

n = int(input().strip())
grid = [list(map(int, input().strip().split())) for _ in range(n)]

q = deque([(0, 0)])
grid[0][0] = 1
pre = [0] * (n * n)

while q:
    x, y = q.popleft()
    for tx, ty in [(x + 1, y), (x, y + 1), (x - 1, y), (x, y - 1)]:
        if 0 <= tx < n and 0 <= ty < n and grid[tx][ty] == 0:
            pre[tx * n + ty] = x * n + y
            grid[tx][ty] = 1
            q.append((tx, ty))

# 递归将倒序储存以正序输出
def print_path(x, y):
    if x * n + y == 0:
        print(x, y)
        return
    k = pre[x * n + y]
    tx, ty = k // n, k % n
    print_path(tx, ty)
    print(x, y)

print_path(n - 1, n - 1)

武士风度的牛

题目描述:

农民 John 有很多牛,他想交易其中一头被 Don 称为 The Knight 的牛。

这头牛有一个独一无二的超能力,在农场里像 Knight 一样地跳(就是我们熟悉的象棋中马的走法)。

虽然这头神奇的牛不能跳到树上和石头上,但是它可以在牧场上随意跳,我们把牧场用一个 x , y x,y x,y 的坐标图来表示。

这头神奇的牛像其它牛一样喜欢吃草,给你一张地图,上面标注了 The Knight 的开始位置,树、灌木、石头以及其它障碍的位置,除此之外还有一捆草。

现在你的任务是,确定 The Knight 要想吃到草,至少需要跳多少次。

The Knight 的位置用 K 来标记,障碍的位置用 * 来标记,草的位置用 H 来标记。

这里有一个地图的例子:

python 复制代码
             11 | . . . . . . . . . .
             10 | . . . . * . . . . . 
              9 | . . . . . . . . . . 
              8 | . . . * . * . . . . 
              7 | . . . . . . . * . . 
              6 | . . * . . * . . . H 
              5 | * . . . . . . . . . 
              4 | . . . * . . . * . . 
              3 | . K . . . . . . . . 
              2 | . . . * . . . . . * 
              1 | . . * . . . . * . . 
              0 ----------------------
                                    1 
                0 1 2 3 4 5 6 7 8 9 0 

The Knight 可以按照下图中的 A , B , C , D ... A,B,C,D... A,B,C,D... 这条路径用 5 5 5 次跳到草的地方(有可能其它路线的长度也是 5 5 5):

python 复制代码
             11 | . . . . . . . . . .
             10 | . . . . * . . . . .
              9 | . . . . . . . . . .
              8 | . . . * . * . . . .
              7 | . . . . . . . * . .
              6 | . . * . . * . . . F<
              5 | * . B . . . . . . .
              4 | . . . * C . . * E .
              3 | .>A . . . . D . . .
              2 | . . . * . . . . . *
              1 | . . * . . . . * . .
              0 ----------------------
                                    1
                0 1 2 3 4 5 6 7 8 9 0

注意: 数据保证一定有解。

输入格式:

第 1 1 1 行: 两个数,表示农场的列数 C C C 和行数 R R R。

第 2 2 2 到 R + 1 R+1 R+1 行:每行一个由 C C C 个字符组成的字符串,共同描绘出牧场地图。

输出格式:

一个整数,表示跳跃的最小次数。

数据范围:

1 ≤ R , C ≤ 150 1≤R,C≤150 1≤R,C≤150

输入样例:

python 复制代码
10 11
..........
....*.....
..........
...*.*....
.......*..
..*..*...H
*.........
...*...*..
.K........
...*.....*
..*....*..

输出样例:

python 复制代码
5

代码实现

python 复制代码
import sys
from collections import defaultdict, deque
input = sys.stdin.readline

m, n = map(int, input().strip().split())
grid = [input().strip() for _ in range(n)]

ex = ey = sx = sy = 0
for i in range(n):
    for j in range(m):
        if grid[i][j] == 'H':
            ex, ey = i, j
        if grid[i][j] == 'K':
            sx, sy = i, j

d = defaultdict(int)
q = deque([(sx, sy)])
d[sx * m + sy] = 0

while q:
    x, y = q.popleft()
    if (x, y) == (ex, ey):
        break
    for tx, ty in [(x - 1, y - 2), (x - 2, y - 1), (x - 2, y + 1), (x - 1, y + 2), (x + 1, y + 2), (x + 2, y + 1), ( x + 2, y - 1), (x + 1, y - 2)]:
        if 0 <= tx < n and 0 <= ty < m and tx * m + ty not in d and grid[tx][ty] != '*':
            q.append((tx, ty))
            d[tx * m + ty] = d[x * m + y] + 1

print(d[ex * m + ey])

抓住那头牛

题目描述:

农夫知道一头牛的位置,想要抓住它。

农夫和牛都位于数轴上,农夫起始位于点 N N N,牛位于点 K K K。

农夫有两种移动方式:

  1. 从 X X X 移动到 X − 1 X-1 X−1 或 X + 1 X+1 X+1,每次移动花费一分钟
  2. 从 X X X 移动到 2 ∗ X 2*X 2∗X,每次移动花费一分钟

假设牛没有意识到农夫的行动,站在原地不动。

农夫 最少 要花多少时间才能抓住牛?

输入格式:

共一行,包含两个整数 N N N 和 K K K。

输出格式:

输出一个整数,表示抓到牛所花费的 最少时间 。

数据范围:

0 ≤ N , K ≤ 1 0 5 0 ≤ N, K ≤ 10^5 0≤N,K≤105

输入样例:

python 复制代码
5 17

输出样例:

python 复制代码
4

代码实现

python 复制代码
import sys
from collections import deque, defaultdict
input = sys.stdin.readline

n, k = map(int, input().strip().split())

q = deque([n])
d = defaultdict(int)
d[n] = 0

while q:
    x = q.popleft()
    if x == k:
        break
    if k < x and 0 <= x - 1 and x - 1 not in d:
        d[x - 1] = d[x] + 1
        q.append(x - 1)
    if k > x:
        for tx in [x + 1, x * 2, x - 1]:
            if 0 <= tx and tx not in d:
                d[tx] = d[x] + 1
                q.append(tx)
print(d[k])
相关推荐
FL16238631292 分钟前
python版本的Selenium的下载及chrome环境搭建和简单使用
chrome·python·selenium
巫师不要去魔法部乱说5 分钟前
PyCharm专项训练5 最短路径算法
python·算法·pycharm
Chloe.Zz12 分钟前
Python基础知识回顾
python
骑个小蜗牛16 分钟前
Python 标准库:random——随机数
python
Trouvaille ~26 分钟前
【机器学习】从流动到恒常,无穷中归一:积分的数学诗意
人工智能·python·机器学习·ai·数据分析·matplotlib·微积分
qystca37 分钟前
洛谷 P11242 碧树 C语言
数据结构·算法
LuH112438 分钟前
【论文阅读笔记】IC-Light
论文阅读·笔记
是十一月末42 分钟前
Opencv实现图像的腐蚀、膨胀及开、闭运算
人工智能·python·opencv·计算机视觉
是小菜呀!43 分钟前
实验四 触发器
笔记
冠位观测者44 分钟前
【Leetcode 热题 100】124. 二叉树中的最大路径和
数据结构·算法·leetcode