数据结构与算法Python版第十一周OJ作业

1 找到小镇的法官(10分)

题目内容:

在一个小镇里,按从 1 到 N 标记了 N 个人。传言称,这些人中有一个是小镇上的秘密法官。

如果小镇的法官真的存在,那么:

  1. 小镇的法官不相信任何人。
  2. 每个人(除了小镇法官外)都信任小镇的法官。
  3. 只有一个人同时满足属性 1 和属性 2 。

给定列表 trust,该列表由信任对 trust[i] = [a, b] 组成,表示标记为 a 的人信任标记为 b 的人。

如果小镇存在秘密法官并且可以确定他的身份,请返回该法官的标记。否则,返回 -1。

输入格式:

输入包含两行,第一行为一个正整数N,第二行为信任对列表trust,以合法的Python表达式给出

输出格式:

一个整数,表示法官的编号

输入样例:

4

[[1,3],[1,4],[2,3],[2,4],[4,3]]

输出样例:

3

解题思路:

用两个列表分别记录每个人信任多少人和被多少人信任,然后通过三个筛选条件找到法官

程序代码:

def findJudge(N):
    trust_list = [0] * (N + 1)
    trusted_list = [0] * (N + 1)
    for i, j in trust:
        trust_list[i] += 1
        trusted_list[j] += 1
    count = 0
    result = []
    for i in range(1, N + 1):
        if trust_list[i] == 0 and trusted_list[i] == N - 1:
            count += 1
            result.append(i)
    if count == 1:
        return result[0]
    else:
        return -1


N = int(input())
trust = eval(input())
print(findJudge(N))

2 远离大陆(10分)

题目内容:

你现在手里有一份大小为 M x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地

对于每个海洋方格,其存在一个距离它最近的陆地方格,相应有一个到陆地的最小距离

请输出上述所有最小距离中的最大值。

我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| + |y0 - y1| 。

如果地图上只有陆地或者海洋,请返回 -1。

输入格式:

输入共1行,为一个仅包含0与1的嵌套列表,用合法的Python表达式给出

输出格式:

一个整数,表示最短距离

输入样例:

[[1,0,1],[0,0,0],[1,0,1]]

输出样例:

2

注:最远的海洋区域坐标为(1,1)

解题思路:

采用BFS宽度优先搜索,先创建一个二维列表用于存储每个格子的曼哈顿距离,先将陆地格子的曼哈顿距离都存为0,接着开始搜索每个陆地格子上下左右四个格子,这些格子的曼哈顿距离都存为1,再接着搜索这些曼哈顿距离为1的格子的上下左右四个格子,这些格子的曼哈顿距离都存为2,重复此操作直到所有格子都被遍历一遍

程序代码:

grid = eval(input())
M = len(grid)
N = len(grid[0])
dist = [[None for _ in range(M)] for _ in range(N)]
queue = []
for i in range(M):
    for j in range(N):
        if grid[i][j]:
            queue.append((i, j))
            dist[i][j] = 0
if queue == [] or len(queue) == M * N:
    print(-1)
else:
    while queue:
        x, y = queue.pop(0)
        for i, j in [(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]:
            if 0 <= i < M and 0 <= j < N and dist[i][j] == None:
                dist[i][j] = dist[x][y] + 1
                queue.append((i, j))
    print(max(max(row) for row in dist))

3 钥匙和房间(10分)

题目内容:

有 N 个房间,开始时你位于 0 号房间。每个房间有不同的号码:0,1,2,…,N-1,并且房间里可能有一些钥匙能使你进入下一个房间。

在形式上,对于每个房间 i 都有一个钥匙列表 rooms[i],每个钥匙 rooms[i][j] 由 [0,1,…,N-1] 中的一个整数表示,其中 N = rooms.length。 钥匙 rooms[i][j] = v 可以打开编号为 v 的房间。

最初,除 0 号房间外的其余所有房间都被锁住。

你可以自由地在房间之间来回走动。

请判断是否可以最终打开所有房间。

输入格式:

一行嵌套列表,列表长度为N,以合法的Python表达式格式给出

输出格式:

True或False,代表是否可以进入每个房间

输入样例:

[[1],[2],[3],[]]

输出样例:

True

解题思路:

采用DFS深度优先搜索,从0号房间开始对每一个钥匙能去的房间调用自身进行深度优先搜索,在搜索过程中每到一个新的房间就记录一次,记录过的房间就不再重复搜索,最后比对记录房间的数量和N是否相等,相等就打印True,反之就打印False

程序代码:

def canVisitAll(n):
    visited.append(n)
    keys = rooms[n]
    for key in keys:
        if key not in visited:
            canVisitAll(key)
    return


rooms = eval(input())
N = len(rooms)
visited = []
canVisitAll(0)
if len(visited) == N:
    print(True)
else:
    print(False)
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值