- 试题名称:邻域均值
- 试题背景:顿顿在学习了数字图像处理后,想要对手上的一副灰度图像进行降噪处理。不过该图像仅在较暗区域有很多噪点,如果贸然对全图进行降噪,会在抹去噪点的同时也模糊了原有图像。因此顿顿打算先使用邻域均值来判断一个像素是否处于较暗区域,然后仅对处于较暗区域的像素进行降噪处理。
- 问题描述:
- 现给定邻域参数r和阈值t,试统计输入灰度图像中有多少像素处于较暗区域。
- 样例输入:
4 16 1 6
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
- 样例输出:
7
- 样例输入:
11 8 2 2
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
0 7 0 0 0 7 0 0 7 7 0
7 0 7 0 7 0 7 0 7 0 7
7 0 0 0 7 0 0 0 7 0 7
7 0 0 0 0 7 0 0 7 7 0
7 0 0 0 0 0 7 0 7 0 0
7 0 7 0 7 0 7 0 7 0 0
0 7 0 0 0 7 0 0 7 0 0
0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0
- 样例输出:
83
- 这里我们用到了一点集合的思想:
- sum[ i ][ j ]里存放的是(i,j)这个位置到(1,1)围成矩形区域内所有数字的和
- 数据矩阵如图所示:
- 如果我们想求S4的面积,只需要将大矩形的面积减去S2,S3,再加上S1即可。至于为什么要加上S1,因为S1这个区域被减去了两次,而事实上,减去一次即可。 下面我们只需要遍历所给的矩阵就可以了。
注意:为什么要用这种思想,是因为一般csp的第二题使用暴力解法得不了满分。形如:
for i in range(n):
for j in range(n):
for k in range(n):
- 这样连续三个for循环一定得不了满分,这和啥编程语言没啥关系,最多二重循环就够了。
n, l, r, t = map(int, input().split())
data = []
count = 0
for i in range(n):
data.append(list(map(int, input().split())))
sum = [[0]*(n+1) for i in range(n+1)]
# 创建前缀和数组,存放的是(i,j)与(1,1)所围成矩形区域内数的和。
for i in range(1, n+1):
for j in range(1, n+1):
sum[i][j] = sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+data[i-1][j-1]
# 判定在邻域范围内,数值和小于阈值的数有多少。
for i in range(1, n+1):
for j in range(1, n+1):
sub_count = 0
i_max = min(n, i+r)
i_min = max(1, i-r) - 1
j_max = min(n, j+r)
j_min = max(1, j-r) - 1
sub_sum = sum[i_max][j_max] - sum[i_max][j_min] -sum[i_min][j_max] + sum[i_min][j_min]
num = (i_max-i_min)*(j_max-j_min)
sub_count = sub_sum/num
if(sub_count <= t):
count += 1
print(count)
可能解释的不太清除,请见谅,但多想想你会发现其实思路挺简单的。加油!