202104-2 邻域均值 [二维前缀和]

202104-2 邻域均值 [二维前缀和]

总结:

在这里插入图片描述

这道题看似不难,但同比于历年的第二题来说,虽然求解不能但是想难满分却实属不易,笔者一开始抱着看似简单的心态,用暴力O(n**3)做完后,却遭到了运行超时的滑铁卢,最后查阅许多算法类资料,才将算法优化,最后运行通过,下面我将详细讲解本题以及读者可能出现的问题答疑。

注意:

  • 若为70 分,且显示运行超时,说明需要优化算法

1. 题目介绍

2. Python代码及题目分析

1. 思路:

  1. 求出每个给定区域大小的均值
  2. 若所求均值小于t,则该点为暗点,count就+1,
  • 关键:由思路我们发现本题难点就是如何利用非暴力算法求解每个区域的均值,至于计算部分,笔者详细大家都会计算。

2. 具体分析:

  1. 在计算中,发现当计算后面点的区域时,我们需要再次计算前面的区域中的点,这样就会有重复的地方,所以我们优化算法的方式就是将重复计算部分去除,这就很容易想到动态规划中的前缀和思想,用空间来换取时间效率,但是即便我们曾经写过前缀和的题也会发现没那么好做,因为这道题是二维前缀和。
  2. 再不断的查阅资料中我发现了一位笔者将二维前缀和的思想描述的特别好,特别容易懂,链接在下面:
  1. 我们利用前缀和的思想,将所有点为截止点的区域和全部计算出来。索引即为该截止点的位置,该索引对应的值即为该截止点区域内值的和,如如图点LJ即为截止点
    在这里插入图片描述
# 二维前缀和求矩阵所有区域值的和以及个数

sum = [ [0]*n for i in range(n)]
for i in range(n):
    for j in range(n):
        # 分成四种情况记录
        if i-1>=0 and j-1>=0: 
            sum[i][j] = Gray_image_matrix[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]
        elif i-1<0 and j-1 >= 0:
            sum[i][j] = Gray_image_matrix[i][j]+sum[i][j-1]
        elif i-0>=0 and j-1 < 0:
            sum[i][j] = Gray_image_matrix[i][j]+sum[i-1][j]
        else :
            sum[i][j] = Gray_image_matrix[i][j]

3. 整体代码

1. 暴力解法(超时70分)
# 输入 灰度图大小n,灰度值范围0~L,较暗区域判断阈值t,领域范围r
n, L, r, t = map(int, input().split())
region_count = 0  # 初始化领域均值计数
Gray_image_matrix = [0] * n
for i in range(n):
    Gray_image_matrix[i] = list(map(int, input().split()))

# 计数所求领域灰度值个数
for i in range(n):
    for j in range(n):
        up, down, left, right = j - r, j + r, i - r, i + r

        # 判断是否越界
        up = max(up, 0)
        down = min(down, n - 1)
        left = max(left, 0)
        right = min(right, n - 1)
        
        # 计算均值
        vaule = 0
        count = 0
        for z in range(up,down+1):
            vaule += sum(Gray_image_matrix[z][left:right+1])
            count += len(Gray_image_matrix[z][left:right+1])
        region_vaule = vaule/count
        if region_vaule <= t:
            region_count += 1
# 输出计数个数
print(region_count)
2. 二维前缀和(100分)
# 输入 灰度图大小n,灰度值范围0~L,较暗区域判断阈值t,领域范围r
n, L, r, t = map(int, input().split())
region_count = 0  # 初始化领域均值计数
Gray_image_matrix = [0] * n
for i in range(n):
    Gray_image_matrix[i] = list(map(int, input().split()))
# 二维前缀和求矩阵所有区域值的和以及个数

sum = [ [0]*n for i in range(n)]
for i in range(n):
    for j in range(n):
        # 分成四种情况记录
        if i-1>=0 and j-1>=0: 
            sum[i][j] = Gray_image_matrix[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]
        elif i-1<0 and j-1 >= 0:
            sum[i][j] = Gray_image_matrix[i][j]+sum[i][j-1]
        elif i-0>=0 and j-1 < 0:
            sum[i][j] = Gray_image_matrix[i][j]+sum[i-1][j]
        else :
            sum[i][j] = Gray_image_matrix[i][j]

# 计数所求领域灰度值个数
for i in range(n):
    for j in range(n):
        up, down, left, right = i - r - 1, i + r, j - r -1 , j + r
        
        # 计算均值 ,因为要包含外界的数所以比r多减1
        down = min(down,n-1)
        right = min(right, n-1)

        if left>=0 and up>=0: 
            vaule = sum[down][right]-sum[down][left]-sum[up][right]+sum[up][left]
        elif left<0 and up >= 0:
            vaule = sum[down][right]-sum[up][right]
            left = -1
        elif left>=0 and up  < 0:
            vaule = sum[down][right]-sum[down][left]
            up = -1
        else :
            vaule = sum[down][right]
            left = up = -1
        count = (right-left)*(down-up)
        region_vaule = vaule/count
        if region_vaule <= t:
            region_count += 1
# 输出计数个数
print(region_count)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿明同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值