监视器个数python

 难度指数:⭐⭐⭐⭐

通用一般算法

1.遍历整个停车场,找到所有已停车的位置。
2.对于每个已停车的位置,检查其上下左右四个方向是否有空位,如果有空位,则在当前位置和相邻的空位处打开监控器。
3.统计打开的监控器数量。

华为OD机考-需要打开多少监视器(C,python)
 

def min_monitors(m, n, parking):
    # 检查x/y都在停车场内
    def is_valid(x, y):
        return 0 <= x < m and 0 <= y < n

    # 定义上下左右四个方向的偏移量
    directions = [(0, 0), (0, 1), (1, 0), (0, -1), (-1, 0)]
    # 创建一个二维数组来标记放置监控器的位置
    cameras = [[0] * n for _ in range(m)]  
    # 初始化监控器数量为0
    count = 0  

    # 遍历停车场
    for i in range(m):
        for j in range(n):
            # 如果当前位置已停车
            if parking[i][j] == 1:
                for dx, dy in directions:
                    nx, ny = i + dx, j + dy
                    
                    if is_valid(nx, ny):
                        cameras[nx][ny] = 1  # 标记相邻位置为已覆盖

    # 统计放置的监控器数量
    for i in range(m):
        for j in range(n):
            if cameras[i][j] == 1:
                count += 1

    return count


 

创新算法

idea

一般的算法,对于单个停车位,重新判断所有五个方位的停车情况,有些冗余。

本算法主要利用了双层循环对停车位有无停车的判断顺序,即自上而下,从左到右。

设计一个二维数组记录目前经判定需要监视器的停车位。

主要分一下两种情况,

  • 对于自身有停车的车位,可以判定自身,其右,其下这三个车位的均需要监视器;
  • 对于后续自身无停车的车位,
    1. 若该位置已被判定需要监视器,则无需再进行任何判定;
    2. 若尚未被判定需要监视器,这意味着其上,其左的车位均未停车,无需对这两个方位的车位进行重复判定,而仅需对其右,其下这两个车位的停车情况进行判断。

注:对于可能超出边界的停车位的判定,需要使用try,except进行pass。

代码实现

def min_monitors0(m, n, parking0):
    certain_p=[list(0 for _ in range(n)) for _ in range(m)]
    directions=[(0,1),(1,0)]
    for i in range(m):
        for j in range(n):
            if parking[i][j]==1:
                certain_p[i][j]=1
                for (dx,dy) in directions:
                    try:
                        certain_p[i+dx][j+dy]=1
                    except:
                        pass
            elif certain_p[i][j]==0: 
                for (dx,dy) in directions:
                    try:
                        if parking[i+dx][j+dy]==1:
                            certain_p[i][j]=1
                            break
                    except:
                        pass
    return sum(map(sum,certain_p))

对比验证

'''
解题思路:
1.遍历整个停车场,找到所有已停车的位置。
2.对于每个已停车的位置,检查其上下左右四个方向是否有空位,如果有空位,则在当前位置和相邻的空位处打开监控器。
3.统计打开的监控器数量。
'''
import random
def min_monitors(m, n, parking):
    # 检查x/y都在停车场内
    def is_valid(x, y):
        return 0 <= x < m and 0 <= y < n

    # 定义上下左右四个方向的偏移量
    directions = [(0, 0), (0, 1), (1, 0), (0, -1), (-1, 0)]
    # 创建一个二维数组来标记放置监控器的位置
    cameras = [[0] * n for _ in range(m)]  
    # 初始化监控器数量为0
    count = 0  

    # 遍历停车场
    for i in range(m):
        for j in range(n):
            # 如果当前位置已停车
            if parking[i][j] == 1:
                for dx, dy in directions:
                    nx, ny = i + dx, j + dy
                    
                    if is_valid(nx, ny):
                        cameras[nx][ny] = 1  # 标记相邻位置为已覆盖

    # 统计放置的监控器数量
    for i in range(m):
        for j in range(n):
            if cameras[i][j] == 1:
                count += 1

    return count

def min_monitors0(m, n, parking0):
    certain_p=[list(0 for _ in range(n)) for _ in range(m)]
    directions=[(0,1),(1,0)]
    for i in range(m):
        for j in range(n):
            if parking[i][j]==1:
                certain_p[i][j]=1
                for (dx,dy) in directions:
                    try:
                        certain_p[i+dx][j+dy]=1
                    except:
                        pass
            elif certain_p[i][j]==0: 
                for (dx,dy) in directions:
                    try:
                        if parking[i+dx][j+dy]==1:
                            certain_p[i][j]=1
                            break
                    except:
                        pass
    return sum(map(sum,certain_p))


# 输入
'''m,n=map(int(),input().split())
parking=[list[map(int(),input().split()) for _ in range(m)]]'''
m,n = [random.randint(2,21) for _ in range(2)]
parking = [[random.randint(0,1) for _ in range(n)] for _ in range(0,m)]
for i in range (0,m):
    print(parking[i]) 
result = min_monitors(m, n, parking)
print(result)
result = min_monitors0(m, n, parking)
print(result)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值